-
Notifications
You must be signed in to change notification settings - Fork 3
/
transfer.go
93 lines (77 loc) · 2.02 KB
/
transfer.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package faucet
import (
"errors"
"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/std"
)
var errNoFundedAccount = errors.New("no funded account found")
// transferFunds transfers funds to the given address
func (f *Faucet) transferFunds(address crypto.Address, amount std.Coins) error {
// Find an account that has balance to cover the transfer
fundAccount, err := f.findFundedAccount(amount)
if err != nil {
return err
}
// Prepare the transaction
pCfg := PrepareCfg{
FromAddress: fundAccount.GetAddress(),
ToAddress: address,
SendAmount: amount,
}
tx := prepareTransaction(f.estimator, f.prepareTxMsgFn(pCfg))
// Sign the transaction
sCfg := signCfg{
chainID: f.config.ChainID,
accountNumber: fundAccount.GetAccountNumber(),
sequence: fundAccount.GetSequence(),
}
if err := signTransaction(
tx,
f.keyring.GetKey(fundAccount.GetAddress()),
sCfg,
); err != nil {
return err
}
// Broadcast the transaction
return broadcastTransaction(f.client, tx)
}
// findFundedAccount finds an account
// whose balance is enough to cover the send amount
func (f *Faucet) findFundedAccount(amount std.Coins) (std.Account, error) {
// A funded account is an account that can
// cover the initial transfer fee, as well
// as the send amount
estimatedFee := f.estimator.EstimateGasFee()
requiredFunds := amount.Add(std.NewCoins(estimatedFee))
for _, address := range f.keyring.GetAddresses() {
// Fetch the account
account, err := f.client.GetAccount(address)
if err != nil {
f.logger.Error(
"unable to fetch account",
"address",
address.String(),
"error",
err,
)
continue
}
// Fetch the balance
balance := account.GetCoins()
// Make sure there are enough funds
if balance.IsAllLT(requiredFunds) {
f.logger.Error(
"account cannot serve requests",
"address",
address.String(),
"balance",
balance.String(),
"amount",
requiredFunds,
)
continue
}
return account, nil
}
return nil, errNoFundedAccount
}