-
Notifications
You must be signed in to change notification settings - Fork 22
/
tx.go
79 lines (64 loc) · 2.18 KB
/
tx.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package client
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// BroadcastTx attempts to generate, sign and broadcast a transaction with the
// given set of messages. It will also simulate gas requirements if necessary.
// It will return an error upon failure.
//
// Note, BroadcastTx is copied from the SDK except it removes a few unnecessary
// things like prompting for confirmation and printing the response. Instead,
// we return the TxResponse.
func BroadcastTx(clientCtx client.Context, txf tx.Factory, msgs ...sdk.Msg) (*sdk.TxResponse, error) {
txf, err := prepareFactory(clientCtx, txf)
if err != nil {
return nil, err
}
if txf.GasAdjustment() > 0 {
_, adjusted, err := tx.CalculateGas(clientCtx, txf, msgs...)
if err != nil {
return nil, err
}
txf = txf.WithGas(adjusted)
}
unsignedTx, err := txf.BuildUnsignedTx(msgs...)
if err != nil {
return nil, err
}
unsignedTx.SetFeeGranter(clientCtx.GetFeeGranterAddress())
// unsignedTx.SetFeePayer(clientCtx.GetFeePayerAddress())
if err = tx.Sign(clientCtx.CmdContext, txf, clientCtx.GetFromName(), unsignedTx, true); err != nil {
return nil, err
}
txBytes, err := clientCtx.TxConfig.TxEncoder()(unsignedTx.GetTx())
if err != nil {
return nil, err
}
return clientCtx.BroadcastTx(txBytes)
}
// prepareFactory ensures the account defined by ctx.GetFromAddress() exists and
// if the account number and/or the account sequence number are zero (not set),
// they will be queried for and set on the provided Factory. A new Factory with
// the updated fields will be returned.
func prepareFactory(clientCtx client.Context, txf tx.Factory) (tx.Factory, error) {
from := clientCtx.GetFromAddress()
if err := txf.AccountRetriever().EnsureExists(clientCtx, from); err != nil {
return txf, err
}
initNum, initSeq := txf.AccountNumber(), txf.Sequence()
if initNum == 0 || initSeq == 0 {
num, seq, err := txf.AccountRetriever().GetAccountNumberSequence(clientCtx, from)
if err != nil {
return txf, err
}
if initNum == 0 {
txf = txf.WithAccountNumber(num)
}
if initSeq == 0 {
txf = txf.WithSequence(seq)
}
}
return txf, nil
}