-
Notifications
You must be signed in to change notification settings - Fork 0
/
xfer.go
95 lines (80 loc) · 2.35 KB
/
xfer.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
94
95
package cmd
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
"github.com/ilgooz/relayer/relayer"
)
// NOTE: These commands are registered over in cmd/raw.go
func xfersend() *cobra.Command {
cmd := &cobra.Command{
Use: "transfer [src-chain-id] [dst-chain-id] [amount] [dst-addr]",
Short: "Initiate a transfer from one chain to another",
Aliases: []string{"xfer", "txf"},
Long: "Sends the first step to transfer tokens in an IBC transfer." +
" The created packet must be relayed to another chain",
Args: cobra.ExactArgs(4),
RunE: func(cmd *cobra.Command, args []string) error {
src, dst := args[0], args[1]
c, err := config.Chains.Gets(src, dst)
if err != nil {
return err
}
pth, err := cmd.Flags().GetString(flagPath)
if err != nil {
return err
}
if _, err = setPathsFromArgs(c[src], c[dst], pth); err != nil {
return err
}
amount, err := sdk.ParseCoin(args[2])
if err != nil {
return err
}
// TODO: add ability to set timeout height and time from flags
// Should be relative to current time and block height
// --timeout-height-offset=1000
// --timeout-time-offset=2h
c[dst].UseSDKContext()
dstAddr, err := sdk.AccAddressFromBech32(args[3])
if err != nil {
return err
}
return c[src].SendTransferMsg(c[dst], amount, dstAddr)
},
}
return pathFlag(cmd)
}
func setPathsFromArgs(src, dst *relayer.Chain, name string) (*relayer.Path, error) {
// Find any configured paths between the chains
paths, err := config.Paths.PathsFromChains(src.ChainID, dst.ChainID)
if err != nil {
return nil, err
}
// Given the number of args and the number of paths,
// work on the appropriate path
var path *relayer.Path
switch {
case name != "" && len(paths) > 1:
if path, err = paths.Get(name); err != nil {
return path, err
}
case name != "" && len(paths) == 1:
if path, err = paths.Get(name); err != nil {
return path, err
}
case name == "" && len(paths) > 1:
return nil, fmt.Errorf("more than one path between %s and %s exists, pass in path name", src.ChainID, dst.ChainID)
case name == "" && len(paths) == 1:
for _, v := range paths {
path = v
}
}
if err = src.SetPath(path.End(src.ChainID)); err != nil {
return nil, err
}
if err = dst.SetPath(path.End(dst.ChainID)); err != nil {
return nil, err
}
return path, nil
}