github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/rpc/author/submit_and_watch_extrinsic.go (about) 1 // Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls 2 // 3 // Copyright 2020 Stafi Protocol 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package author 18 19 import ( 20 "context" 21 "sync" 22 23 "github.com/stafiprotocol/go-substrate-rpc-client/config" 24 gethrpc "github.com/stafiprotocol/go-substrate-rpc-client/pkg/gethrpc" 25 "github.com/stafiprotocol/go-substrate-rpc-client/types" 26 ) 27 28 // ExtrinsicStatusSubscription is a subscription established through one of the Client's subscribe methods. 29 type ExtrinsicStatusSubscription struct { 30 sub *gethrpc.ClientSubscription 31 channel chan types.ExtrinsicStatus 32 quitOnce sync.Once // ensures quit is closed once 33 } 34 35 // Chan returns the subscription channel. 36 // 37 // The channel is closed when Unsubscribe is called on the subscription. 38 func (s *ExtrinsicStatusSubscription) Chan() <-chan types.ExtrinsicStatus { 39 return s.channel 40 } 41 42 // Err returns the subscription error channel. The intended use of Err is to schedule 43 // resubscription when the client connection is closed unexpectedly. 44 // 45 // The error channel receives a value when the subscription has ended due 46 // to an error. The received error is nil if Close has been called 47 // on the underlying client and no other error has occurred. 48 // 49 // The error channel is closed when Unsubscribe is called on the subscription. 50 func (s *ExtrinsicStatusSubscription) Err() <-chan error { 51 return s.sub.Err() 52 } 53 54 // Unsubscribe unsubscribes the notification and closes the error channel. 55 // It can safely be called more than once. 56 func (s *ExtrinsicStatusSubscription) Unsubscribe() { 57 s.sub.Unsubscribe() 58 s.quitOnce.Do(func() { 59 close(s.channel) 60 }) 61 } 62 63 // SubmitAndWatchExtrinsic will submit and subscribe to watch an extrinsic until unsubscribed, returning a subscription 64 // that will receive server notifications containing the extrinsic status updates. 65 func (a *Author) SubmitAndWatchExtrinsic(xt types.Extrinsic) (*ExtrinsicStatusSubscription, error) { //nolint:lll 66 ctx, cancel := context.WithTimeout(context.Background(), config.Default().SubscribeTimeout) 67 defer cancel() 68 69 c := make(chan types.ExtrinsicStatus) 70 71 enc, err := types.EncodeToHexString(xt) 72 if err != nil { 73 return nil, err 74 } 75 76 sub, err := a.client.Subscribe(ctx, "author", "submitAndWatchExtrinsic", "unwatchExtrinsic", "extrinsicUpdate", 77 c, enc) 78 if err != nil { 79 return nil, err 80 } 81 82 return &ExtrinsicStatusSubscription{sub: sub, channel: c}, nil 83 } 84 85 func (a *Author) SubmitAndWatch(xt interface{}) (*ExtrinsicStatusSubscription, error) { //nolint:lll 86 ctx, cancel := context.WithTimeout(context.Background(), config.Default().SubscribeTimeout) 87 defer cancel() 88 89 c := make(chan types.ExtrinsicStatus) 90 91 enc, err := types.EncodeToHexString(xt) 92 if err != nil { 93 return nil, err 94 } 95 96 sub, err := a.client.Subscribe(ctx, "author", "submitAndWatchExtrinsic", "unwatchExtrinsic", "extrinsicUpdate", 97 c, enc) 98 if err != nil { 99 return nil, err 100 } 101 102 return &ExtrinsicStatusSubscription{sub: sub, channel: c}, nil 103 }