Terra support added (#79)
This commit adds initial support for the Terra blockchain.
This commit is contained in:
parent
e0ca52deb5
commit
1ca2e29916
9
Tiltfile
9
Tiltfile
|
@ -146,3 +146,12 @@ k8s_yaml("devnet/web.yaml")
|
|||
k8s_resource("web", port_forwards=[
|
||||
port_forward(3000, name="Experimental Web UI [:3000]")
|
||||
])
|
||||
|
||||
# terra devnet
|
||||
|
||||
k8s_yaml("devnet/terra-devnet.yaml")
|
||||
|
||||
k8s_resource("terra-lcd", port_forwards=[
|
||||
port_forward(1317, name="Terra LCD interface [:1317]")
|
||||
])
|
||||
k8s_resource("terra-terrad")
|
|
@ -25,6 +25,8 @@ import (
|
|||
"github.com/certusone/wormhole/bridge/pkg/supervisor"
|
||||
"github.com/certusone/wormhole/bridge/pkg/vaa"
|
||||
|
||||
"github.com/certusone/wormhole/bridge/pkg/terra"
|
||||
|
||||
ipfslog "github.com/ipfs/go-log/v2"
|
||||
)
|
||||
|
||||
|
@ -39,6 +41,13 @@ var (
|
|||
ethContract *string
|
||||
ethConfirmations *uint64
|
||||
|
||||
terraSupport *bool
|
||||
terraWS *string
|
||||
terraLCD *string
|
||||
terraChaidID *string
|
||||
terraContract *string
|
||||
terraFeePayer *string
|
||||
|
||||
agentRPC *string
|
||||
|
||||
logLevel *string
|
||||
|
@ -59,6 +68,13 @@ func init() {
|
|||
ethContract = BridgeCmd.Flags().String("ethContract", "", "Ethereum bridge contract address")
|
||||
ethConfirmations = BridgeCmd.Flags().Uint64("ethConfirmations", 15, "Ethereum confirmation count requirement")
|
||||
|
||||
terraSupport = BridgeCmd.Flags().Bool("terra", false, "Turn on support for Terra")
|
||||
terraWS = BridgeCmd.Flags().String("terraWS", "", "Path to terrad root for websocket connection")
|
||||
terraLCD = BridgeCmd.Flags().String("terraLCD", "", "Path to LCD service root for http calls")
|
||||
terraChaidID = BridgeCmd.Flags().String("terraChainID", "", "Terra chain ID, used in LCD client initialization")
|
||||
terraContract = BridgeCmd.Flags().String("terraContract", "", "Wormhole contract address on Terra blockhain")
|
||||
terraFeePayer = BridgeCmd.Flags().String("terraFeePayer", "", "Mnemonic to account paying gas for submitting transactions to Terra")
|
||||
|
||||
agentRPC = BridgeCmd.Flags().String("agentRPC", "", "Solana agent sidecar gRPC address")
|
||||
|
||||
logLevel = BridgeCmd.Flags().String("logLevel", "info", "Logging level (debug, info, warn, error, dpanic, panic, fatal)")
|
||||
|
@ -180,6 +196,23 @@ func runBridge(cmd *cobra.Command, args []string) {
|
|||
if *nodeName == "" {
|
||||
logger.Fatal("Please specify -nodeName")
|
||||
}
|
||||
if *terraSupport {
|
||||
if *terraWS == "" {
|
||||
logger.Fatal("Please specify -terraWS")
|
||||
}
|
||||
if *terraLCD == "" {
|
||||
logger.Fatal("Please specify -terraLCD")
|
||||
}
|
||||
if *terraChaidID == "" {
|
||||
logger.Fatal("Please specify -terraChaidID")
|
||||
}
|
||||
if *terraContract == "" {
|
||||
logger.Fatal("Please specify -terraContract")
|
||||
}
|
||||
if *terraFeePayer == "" {
|
||||
logger.Fatal("Please specify -terraFeePayer")
|
||||
}
|
||||
}
|
||||
|
||||
ethContractAddr := eth_common.HexToAddress(*ethContract)
|
||||
|
||||
|
@ -232,12 +265,21 @@ func runBridge(cmd *cobra.Command, args []string) {
|
|||
return err
|
||||
}
|
||||
|
||||
// Start Terra watcher only if configured
|
||||
if *terraSupport {
|
||||
logger.Info("Starting Terra watcher")
|
||||
if err := supervisor.Run(ctx, "terrawatch",
|
||||
terra.NewTerraBridgeWatcher(*terraWS, *terraLCD, *terraContract, lockC, setC).Run); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := supervisor.Run(ctx, "solwatch",
|
||||
solana.NewSolanaBridgeWatcher(*agentRPC, lockC, solanaVaaC).Run); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p := processor.NewProcessor(ctx, lockC, setC, sendC, obsvC, solanaVaaC, gk, *unsafeDevMode, *devNumGuardians, *ethRPC)
|
||||
p := processor.NewProcessor(ctx, lockC, setC, sendC, obsvC, solanaVaaC, gk, *unsafeDevMode, *devNumGuardians, *ethRPC, *terraLCD, *terraChaidID, *terraContract, *terraFeePayer)
|
||||
if err := supervisor.Run(ctx, "processor", p.Run); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -5,12 +5,13 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
||||
"github.com/certusone/wormhole/bridge/pkg/devnet"
|
||||
"github.com/certusone/wormhole/bridge/pkg/vaa"
|
||||
)
|
||||
|
|
|
@ -7,6 +7,8 @@ require (
|
|||
github.com/aristanetworks/goarista v0.0.0-20201012165903-2cb20defcd66 // indirect
|
||||
github.com/btcsuite/btcd v0.21.0-beta // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.0
|
||||
github.com/cosmos/cosmos-sdk v0.39.1
|
||||
github.com/cosmos/go-bip39 v0.0.0-20200817134856-d632e0d11689
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||
github.com/deckarep/golang-set v1.7.1 // indirect
|
||||
github.com/ethereum/go-ethereum v1.9.23
|
||||
|
@ -14,6 +16,7 @@ require (
|
|||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/golang/snappy v0.0.2 // indirect
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/ipfs/go-log/v2 v2.1.1
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
||||
|
@ -40,12 +43,17 @@ require (
|
|||
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/peterh/liner v1.2.0 // indirect
|
||||
github.com/prometheus/common v0.9.1
|
||||
github.com/prometheus/tsdb v0.10.0 // indirect
|
||||
github.com/shirou/gopsutil v2.20.9+incompatible // indirect
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/viper v1.3.2
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/viper v1.6.3
|
||||
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/tendermint/tendermint v0.33.8
|
||||
github.com/terra-project/terra.go v1.0.1-0.20201113170042-b3bffdc6fd06
|
||||
github.com/tidwall/gjson v1.6.3
|
||||
github.com/tidwall/match v1.0.2 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
|
||||
go.opencensus.io v0.22.5 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
|
|
298
bridge/go.sum
298
bridge/go.sum
|
@ -7,6 +7,8 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
|
|||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/99designs/keyring v1.1.3 h1:mEV3iyZWjkxQ7R8ia8GcG97vCX5zQQ7n4o8R2BylwQY=
|
||||
github.com/99designs/keyring v1.1.3/go.mod h1:657DQuMrBZRtuL/voxVyiyb6zpMehlm5vLB9Qwrv904=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
|
@ -25,9 +27,13 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt
|
|||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
|
||||
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
|
||||
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
|
||||
github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
|
@ -37,16 +43,23 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUW
|
|||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
|
||||
github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
|
||||
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
|
||||
github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||
github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||
|
@ -56,16 +69,28 @@ github.com/aristanetworks/goarista v0.0.0-20190912214011-b54698eaaca6/go.mod h1:
|
|||
github.com/aristanetworks/goarista v0.0.0-20201012165903-2cb20defcd66 h1:bylzF2sl5pWmmHcdwEku/BPHp5wYjcdjmOnW4siw688=
|
||||
github.com/aristanetworks/goarista v0.0.0-20201012165903-2cb20defcd66/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE=
|
||||
github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d/go.mod h1:icNx/6QdFblhsEjZehARqbNumymUT/ydwlLojFdv7Sk=
|
||||
github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
||||
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0=
|
||||
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
||||
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
|
@ -74,6 +99,7 @@ github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13P
|
|||
github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M=
|
||||
github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
|
@ -87,10 +113,14 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg
|
|||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc=
|
||||
github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certusone/wormhole v0.0.0-20201025075704-8d7a35683e63 h1:3UgjvZJVnrX0c4ZsiSiCYM3aKQFza2Y8WbNN75gPCSw=
|
||||
github.com/certusone/wormhole v0.0.0-20201029145145-47ce56749883 h1:HMpUQtatDbrg2Y5AojJPWLmMjJUMxoCUg6v/E1kGZQ8=
|
||||
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
|
||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
|
@ -99,18 +129,37 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+
|
|||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
|
||||
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cosmos/cosmos-sdk v0.39.1 h1:vhjf9PZh9ph8btAj9aBpHoVITgVVjNBpM3x5Gl/Vwac=
|
||||
github.com/cosmos/cosmos-sdk v0.39.1/go.mod h1:ry2ROl5n+f2/QXpKJo3rdWNJwll00z7KhIVcxNcl16M=
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
|
||||
github.com/cosmos/go-bip39 v0.0.0-20200817134856-d632e0d11689 h1:LApiux6F9SuXR5wVKBplzLJli1wm/wrlH5KYFMicCfQ=
|
||||
github.com/cosmos/go-bip39 v0.0.0-20200817134856-d632e0d11689/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
|
||||
github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
|
||||
github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
@ -136,7 +185,10 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
|
|||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a h1:mq+R6XEM6lJX5VlLyZIrUSP8tSuJp82xTK89hvBwJbU=
|
||||
github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
|
@ -147,6 +199,7 @@ github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt
|
|||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
|
@ -154,7 +207,11 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
|||
github.com/ethereum/go-ethereum v1.9.5/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||
github.com/ethereum/go-ethereum v1.9.23 h1:SIKhg/z4Q7AbvqcxuPYvMxf36che/Rq/Pp0IdYEkbtw=
|
||||
github.com/ethereum/go-ethereum v1.9.23/go.mod h1:JIfVb6esrqALTExdz9hRYvrP0xBDf6wCncIu1hNwHpM=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc h1:jtW8jbpkO4YirRSyepBOH8E+2HEw6/hKkBvFPwhUN8c=
|
||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
|
@ -163,6 +220,8 @@ github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe
|
|||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
|
@ -181,22 +240,32 @@ github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
|
|||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE=
|
||||
|
@ -204,6 +273,7 @@ github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4er
|
|||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
|
@ -229,6 +299,8 @@ github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26/go.mod h1:/XxbfmMg
|
|||
github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
|
@ -238,6 +310,7 @@ github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
|||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||
|
@ -254,23 +327,53 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
|
||||
github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
|
||||
github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is=
|
||||
github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
|
||||
github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc=
|
||||
github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
|
||||
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
|
||||
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
|
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
|
@ -278,9 +381,14 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l
|
|||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/holiman/uint256 v1.1.1 h1:4JywC80b+/hSfljFlEBLHrrh+CIONLDz9NuFl0af4Mw=
|
||||
github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo=
|
||||
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
|
@ -354,11 +462,15 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0
|
|||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0=
|
||||
|
@ -367,6 +479,8 @@ github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM5
|
|||
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 h1:ZHuwnjpP8LsVsUYqTqeVAI+GfDfJ6UNPrExZF+vX/DQ=
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM=
|
||||
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
|
@ -596,11 +710,16 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h
|
|||
github.com/libp2p/go-yamux v1.3.9/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE=
|
||||
github.com/libp2p/go-yamux v1.4.0 h1:7nqe0T95T2CWh40IdJ/tp8RMor4ubc9/wYZpB2a/Hx0=
|
||||
github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys=
|
||||
github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
|
||||
|
@ -616,34 +735,49 @@ github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0X
|
|||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20200123000308-a60dcd172b4c h1:cbhK2JT4nl7k8frmCN98ttRdSGP75x9mDxDhlQ1kHQQ=
|
||||
github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20200123000308-a60dcd172b4c/go.mod h1:Z4zI+CdJB1fyrZ1jfevFH6flNV9izrLZnQAeuD6Wkjk=
|
||||
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0=
|
||||
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||
github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc=
|
||||
github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
|
||||
github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
|
||||
github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
|
||||
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -712,11 +846,21 @@ github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS
|
|||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c h1:1RHs3tNxjXGHeul8z2t6H2N2TlAqpKe5yryJztRx4Jk=
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
|
@ -739,13 +883,22 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
|||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
|
||||
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
|
@ -753,11 +906,16 @@ github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
|
|||
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
|
||||
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM=
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
||||
github.com/peterh/liner v1.2.0 h1:w/UPXyl5GfahFxcTOz2j9wCIHNI+pUPr2laqpojKNCg=
|
||||
github.com/peterh/liner v1.2.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
||||
github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
@ -766,35 +924,56 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
|
||||
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.0.10 h1:QJQN3jYQhkamO4mhfUWqdDH2asK7ONOI9MTWjyAxNKM=
|
||||
github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150 h1:ZeU+auZj1iNzN8iVhff6M38Mfu73FQiJve/GEXYJBjE=
|
||||
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
|
||||
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
|
||||
github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||
github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8=
|
||||
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
|
@ -803,7 +982,10 @@ github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubr
|
|||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil v2.20.5+incompatible h1:tYH07UPoQt0OCQdgWWMgYHy3/a9bcxNpBIysykNIP7I=
|
||||
github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
|
@ -833,8 +1015,14 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
|||
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY=
|
||||
github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0=
|
||||
|
@ -845,16 +1033,29 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
|
|||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M=
|
||||
github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.6.3 h1:pDDu1OyEDTKzpJwdq4TiuLyMsUgRa/BT5cn5O62NoHs=
|
||||
github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw=
|
||||
github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc=
|
||||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg=
|
||||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
|
||||
|
@ -864,30 +1065,71 @@ github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1
|
|||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/goleveldb v0.0.0-20180621010148-0d5a0ceb10cf/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||
github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s=
|
||||
github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U=
|
||||
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI=
|
||||
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk=
|
||||
github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso=
|
||||
github.com/tendermint/go-amino v0.15.1 h1:D2uk35eT4iTsvJd9jWIetzthE5C0/k2QmMFkCN+4JgQ=
|
||||
github.com/tendermint/go-amino v0.15.1/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
|
||||
github.com/tendermint/iavl v0.14.0/go.mod h1:QmfViflFiXzxKLQE4tAUuWQHq+RSuQFxablW5oJZ6sE=
|
||||
github.com/tendermint/tendermint v0.33.5/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM=
|
||||
github.com/tendermint/tendermint v0.33.7/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM=
|
||||
github.com/tendermint/tendermint v0.33.8 h1:Xxu4QhpqcomSE0iQDw1MqLgfsa8fqtPtWFJK6zZOVso=
|
||||
github.com/tendermint/tendermint v0.33.8/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM=
|
||||
github.com/tendermint/tm-db v0.5.1 h1:H9HDq8UEA7Eeg13kdYckkgwwkQLBnJGgX4PgLJRhieY=
|
||||
github.com/tendermint/tm-db v0.5.1/go.mod h1:g92zWjHpCYlEvQXvy9M168Su8V1IBEeawpXVVBaK4f4=
|
||||
github.com/terra-project/terra.go v0.0.0-20201112132816-3eb55b358ed6 h1:P3aCNycSUafF3ctydWIrMvI9AmIdQZwBEqIcaVd29uc=
|
||||
github.com/terra-project/terra.go v0.0.0-20201112132816-3eb55b358ed6/go.mod h1:w+V/aEgQEeMuxV9ZnA3J0FUGjg1qBNi3WOr8/yphh/U=
|
||||
github.com/terra-project/terra.go v1.0.0 h1:TR2b3x8yrljXhrs9a3KORRCQ6BGr+bCTp0ZwTrG/i3c=
|
||||
github.com/terra-project/terra.go v1.0.0/go.mod h1:w+V/aEgQEeMuxV9ZnA3J0FUGjg1qBNi3WOr8/yphh/U=
|
||||
github.com/terra-project/terra.go v1.0.1-0.20201113170042-b3bffdc6fd06 h1:TAhaL+7VYJe44qBEKqjlj3wD0CRjJN1JZfz8p+L6FGY=
|
||||
github.com/terra-project/terra.go v1.0.1-0.20201113170042-b3bffdc6fd06/go.mod h1:elzj1F6B9Sel3c4QFNeR3yR4E9tu+c1xBP+ZZYPlSq8=
|
||||
github.com/tidwall/gjson v1.6.3 h1:aHoiiem0dr7GHkW001T1SMTJ7X5PvyekH5WX0whWGnI=
|
||||
github.com/tidwall/gjson v1.6.3/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0=
|
||||
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
|
||||
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/match v1.0.2 h1:uuqvHuBGSedK7awZ2YoAtpnimfwBGFjHuWLuLqQj+bU=
|
||||
github.com/tidwall/match v1.0.2/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
|
||||
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
|
||||
github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tyler-smith/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
||||
github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
|
@ -906,11 +1148,18 @@ github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+m
|
|||
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||
github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
|
@ -919,7 +1168,9 @@ go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
|||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
|
@ -927,6 +1178,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
|||
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
|
||||
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
|
@ -934,6 +1186,7 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i
|
|||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
|
||||
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
|
@ -943,6 +1196,7 @@ go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1
|
|||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -955,17 +1209,22 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -975,6 +1234,7 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+o
|
|||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
|
@ -990,22 +1250,31 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
|
@ -1027,14 +1296,18 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -1047,13 +1320,18 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -1090,6 +1368,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
|
@ -1099,6 +1379,7 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69 h1:yBHHx+XZqXJBm6Exke3N7V9gnlsyXxoCPEb1yVenjfk=
|
||||
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd h1:hHkvGJK23seRCflePJnVa9IMv8fsuavSCWKd11kDQFs=
|
||||
|
@ -1112,6 +1393,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
|
|||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
@ -1123,6 +1405,7 @@ google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk
|
|||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||
|
@ -1133,13 +1416,19 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE
|
|||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.0 h1:IBKSUNL2uBS2DkJBncPP+TwT0sp9tgA8A75NjHt6umg=
|
||||
google.golang.org/grpc v1.33.0/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
|
@ -1161,10 +1450,14 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fatih/set.v0 v0.2.1/go.mod h1:5eLWEndGL4zGGemXWrKuts+wTJR0y+w+auqUJZbmyBg=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||
|
@ -1177,12 +1470,15 @@ gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHN
|
|||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
|
||||
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -1202,5 +1498,7 @@ honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXe
|
|||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/miguelmota/go-ethereum-hdwallet"
|
||||
hdwallet "github.com/miguelmota/go-ethereum-hdwallet"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -7,12 +7,14 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/certusone/wormhole/bridge/pkg/terra"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/certusone/wormhole/bridge/pkg/devnet"
|
||||
"github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1"
|
||||
gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1"
|
||||
"github.com/certusone/wormhole/bridge/pkg/vaa"
|
||||
)
|
||||
|
||||
|
@ -137,19 +139,25 @@ func (p *Processor) handleObservation(ctx context.Context, m *gossipv1.LockupObs
|
|||
}
|
||||
|
||||
if t, ok := v.Payload.(*vaa.BodyTransfer); ok {
|
||||
switch {
|
||||
case t.TargetChain == vaa.ChainIDEthereum:
|
||||
// Check whether we run in devmode and submit the VAA ourselves, if so.
|
||||
p.devnetVAASubmission(ctx, signed, hash)
|
||||
|
||||
// Cross-submit to Solana for data availability
|
||||
fallthrough
|
||||
case t.TargetChain == vaa.ChainIDSolana:
|
||||
switch t.TargetChain {
|
||||
case vaa.ChainIDEthereum,
|
||||
vaa.ChainIDSolana,
|
||||
vaa.ChainIDTerra:
|
||||
// Submit to Solana if target is Solana, but also cross-submit all other targets to Solana for data availability
|
||||
p.logger.Info("submitting signed VAA to Solana",
|
||||
zap.String("digest", hash),
|
||||
zap.Any("vaa", signed),
|
||||
zap.String("bytes", hex.EncodeToString(vaaBytes)))
|
||||
|
||||
switch t.TargetChain {
|
||||
case vaa.ChainIDEthereum:
|
||||
// Check whether we run in devmode and submit the VAA ourselves, if so.
|
||||
p.devnetVAASubmission(ctx, signed, hash)
|
||||
case vaa.ChainIDTerra:
|
||||
p.terraVAASubmission(ctx, signed, hash)
|
||||
}
|
||||
|
||||
p.vaaC <- signed
|
||||
default:
|
||||
p.logger.Error("we don't know how to submit this VAA",
|
||||
|
@ -190,3 +198,19 @@ func (p *Processor) devnetVAASubmission(ctx context.Context, signed *vaa.VAA, ha
|
|||
p.logger.Info("lockup submitted to Ethereum", zap.Any("tx", tx), zap.String("digest", hash))
|
||||
}
|
||||
}
|
||||
|
||||
// Submit VAA to Terra
|
||||
func (p *Processor) terraVAASubmission(ctx context.Context, signed *vaa.VAA, hash string) {
|
||||
tx, err := terra.SubmitVAA(ctx, p.terraLCD, p.terraChaidID, p.terraContract, p.terraFeePayer, signed)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "VaaAlreadyExecuted") {
|
||||
p.logger.Info("lockup already submitted to Terra by another node, ignoring",
|
||||
zap.Error(err), zap.String("digest", hash))
|
||||
} else {
|
||||
p.logger.Error("failed to submit lockup to Terra",
|
||||
zap.Error(err), zap.String("digest", hash))
|
||||
}
|
||||
return
|
||||
}
|
||||
p.logger.Info("lockup submitted to Terra", zap.Any("tx", tx), zap.String("digest", hash))
|
||||
}
|
||||
|
|
|
@ -58,6 +58,11 @@ type Processor struct {
|
|||
devnetNumGuardians uint
|
||||
devnetEthRPC string
|
||||
|
||||
terraLCD string
|
||||
terraChaidID string
|
||||
terraContract string
|
||||
terraFeePayer string
|
||||
|
||||
logger *zap.Logger
|
||||
|
||||
// Runtime state
|
||||
|
@ -82,7 +87,11 @@ func NewProcessor(
|
|||
gk *ecdsa.PrivateKey,
|
||||
devnetMode bool,
|
||||
devnetNumGuardians uint,
|
||||
devnetEthRPC string) *Processor {
|
||||
devnetEthRPC string,
|
||||
terraLCD string,
|
||||
terraChaidID string,
|
||||
terraContract string,
|
||||
terraFeePayer string) *Processor {
|
||||
|
||||
return &Processor{
|
||||
lockC: lockC,
|
||||
|
@ -95,6 +104,11 @@ func NewProcessor(
|
|||
devnetNumGuardians: devnetNumGuardians,
|
||||
devnetEthRPC: devnetEthRPC,
|
||||
|
||||
terraLCD: terraLCD,
|
||||
terraChaidID: terraChaidID,
|
||||
terraContract: terraContract,
|
||||
terraFeePayer: terraFeePayer,
|
||||
|
||||
logger: supervisor.Logger(ctx),
|
||||
state: &aggregationState{vaaMap{}},
|
||||
ourAddr: crypto.PubkeyToAddress(gk.PublicKey),
|
||||
|
@ -139,12 +153,12 @@ func (p *Processor) checkDevModeGuardianSetUpdate(ctx context.Context) error {
|
|||
|
||||
timeout, cancel := context.WithTimeout(ctx, 15*time.Second)
|
||||
defer cancel()
|
||||
tx, err := devnet.SubmitVAA(timeout, p.devnetEthRPC, v)
|
||||
trx, err := devnet.SubmitVAA(timeout, p.devnetEthRPC, v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to submit devnet guardian set change: %v", err)
|
||||
}
|
||||
|
||||
p.logger.Info("devnet guardian set change submitted to Ethereum", zap.Any("tx", tx), zap.Any("vaa", v))
|
||||
p.logger.Info("devnet guardian set change submitted to Ethereum", zap.Any("trx", trx), zap.Any("vaa", v))
|
||||
|
||||
// Submit VAA to Solana as well. This is asynchronous and can fail, leading to inconsistent devnet state.
|
||||
p.vaaC <- v
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package terra
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/certusone/wormhole/bridge/pkg/vaa"
|
||||
"github.com/terra-project/terra.go/client"
|
||||
"github.com/terra-project/terra.go/key"
|
||||
"github.com/terra-project/terra.go/msg"
|
||||
"github.com/terra-project/terra.go/tx"
|
||||
)
|
||||
|
||||
type JSONArraySlice []uint8
|
||||
|
||||
func (u JSONArraySlice) MarshalJSON() ([]uint8, error) {
|
||||
var result string
|
||||
if u == nil {
|
||||
result = "null"
|
||||
} else {
|
||||
result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",")
|
||||
}
|
||||
return []byte(result), nil
|
||||
}
|
||||
|
||||
type SubmitVAAMsg struct {
|
||||
Params SubmitVAAParams `json:"submit_v_a_a"`
|
||||
}
|
||||
|
||||
type SubmitVAAParams struct {
|
||||
VAA JSONArraySlice `json:"vaa"`
|
||||
}
|
||||
|
||||
// SubmitVAA prepares transaction with signed VAA and sends it to the Terra blockchain
|
||||
func SubmitVAA(ctx context.Context, urlLCD string, chainID string, contractAddress string, feePayer string, signed *vaa.VAA) (*client.TxResponse, error) {
|
||||
|
||||
// Serialize VAA
|
||||
vaaBytes, err := signed.Marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Derive Raw Private Key
|
||||
privKey, err := key.DerivePrivKey(feePayer, key.CreateHDPath(0, 0))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Generate StdPrivKey
|
||||
tmKey, err := key.StdPrivKeyGen(privKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Generate Address from Public Key
|
||||
addr := msg.AccAddress(tmKey.PubKey().Address())
|
||||
|
||||
// Create LCDClient
|
||||
LCDClient := client.NewLCDClient(
|
||||
urlLCD,
|
||||
chainID,
|
||||
msg.NewDecCoinFromDec("uusd", msg.NewDecFromIntWithPrec(msg.NewInt(15), 2)), // 0.15uusd
|
||||
msg.NewDecFromIntWithPrec(msg.NewInt(15), 1), tmKey, time.Second*15,
|
||||
)
|
||||
|
||||
contract, err := msg.AccAddressFromBech32(contractAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create tx
|
||||
contractCall, err := json.Marshal(SubmitVAAMsg{
|
||||
Params: SubmitVAAParams{
|
||||
VAA: vaaBytes,
|
||||
}})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
executeContract := msg.NewExecuteContract(addr, contract, contractCall, msg.NewCoins())
|
||||
|
||||
transaction, err := LCDClient.CreateAndSignTx(ctx, client.CreateTxOptions{
|
||||
Msgs: []msg.Msg{
|
||||
executeContract,
|
||||
},
|
||||
Fee: tx.StdFee{
|
||||
Gas: msg.NewInt(0),
|
||||
Amount: msg.NewCoins(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Broadcast
|
||||
return LCDClient.Broadcast(ctx, transaction)
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
package terra
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
eth_common "github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/certusone/wormhole/bridge/pkg/common"
|
||||
"github.com/certusone/wormhole/bridge/pkg/supervisor"
|
||||
"github.com/certusone/wormhole/bridge/pkg/vaa"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/tidwall/gjson"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
// BridgeWatcher is responsible for looking over Terra blockchain and reporting new transactions to the bridge
|
||||
BridgeWatcher struct {
|
||||
urlWS string
|
||||
urlLCD string
|
||||
bridge string
|
||||
|
||||
lockChan chan *common.ChainLock
|
||||
setChan chan *common.GuardianSet
|
||||
}
|
||||
)
|
||||
|
||||
type clientRequest struct {
|
||||
JSONRPC string `json:"jsonrpc"`
|
||||
// A String containing the name of the method to be invoked.
|
||||
Method string `json:"method"`
|
||||
// Object to pass as request parameter to the method.
|
||||
Params [1]string `json:"params"`
|
||||
// The request id. This can be of any type. It is used to match the
|
||||
// response with the request that it is replying to.
|
||||
ID uint64 `json:"id"`
|
||||
}
|
||||
|
||||
// NewTerraBridgeWatcher creates a new terra bridge watcher
|
||||
func NewTerraBridgeWatcher(urlWS string, urlLCD string, bridge string, lockEvents chan *common.ChainLock, setEvents chan *common.GuardianSet) *BridgeWatcher {
|
||||
return &BridgeWatcher{urlWS: urlWS, urlLCD: urlLCD, bridge: bridge, lockChan: lockEvents, setChan: setEvents}
|
||||
}
|
||||
|
||||
// Run is the main Terra Bridge run cycle
|
||||
func (e *BridgeWatcher) Run(ctx context.Context) error {
|
||||
errC := make(chan error)
|
||||
logger := supervisor.Logger(ctx)
|
||||
|
||||
logger.Info("connecting to", zap.String("url", e.urlLCD))
|
||||
|
||||
c, _, err := websocket.DefaultDialer.DialContext(ctx, e.urlLCD, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("socket dial failed: %w", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
// Subscribe to smart contract transactions
|
||||
params := [...]string{fmt.Sprintf("tm.event='Tx' AND execute_contract.contract_address='%s'", e.bridge)}
|
||||
command := &clientRequest{
|
||||
JSONRPC: "2.0",
|
||||
Method: "subscribe",
|
||||
Params: params,
|
||||
ID: 1,
|
||||
}
|
||||
err = c.WriteJSON(command)
|
||||
if err != nil {
|
||||
return fmt.Errorf("websocket subscription failed: %w", err)
|
||||
}
|
||||
|
||||
// Wait for the success response
|
||||
_, _, err = c.ReadMessage()
|
||||
if err != nil {
|
||||
return fmt.Errorf("event subscription failed: %w", err)
|
||||
}
|
||||
logger.Info("Subscribed to new transaction events")
|
||||
|
||||
go func() {
|
||||
defer close(errC)
|
||||
|
||||
for {
|
||||
_, message, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
logger.Error("error reading channel", zap.Error(err))
|
||||
errC <- err
|
||||
return
|
||||
}
|
||||
|
||||
// Received a message from the blockchain
|
||||
json := string(message)
|
||||
targetChain := gjson.Get(json, "result.events.from_contract\\.locked\\.target_chain.0")
|
||||
tokenChain := gjson.Get(json, "result.events.from_contract\\.locked\\.token_chain.0")
|
||||
tokenDecimals := gjson.Get(json, "result.events.from_contract\\.locked\\.token_decimals.0")
|
||||
token := gjson.Get(json, "result.events.from_contract\\.locked\\.token.0")
|
||||
sender := gjson.Get(json, "result.events.from_contract\\.locked\\.sender.0")
|
||||
recipient := gjson.Get(json, "result.events.from_contract\\.locked\\.recipient.0")
|
||||
amount := gjson.Get(json, "result.events.from_contract\\.locked\\.amount.0")
|
||||
nonce := gjson.Get(json, "result.events.from_contract\\.locked\\.nonce.0")
|
||||
txHash := gjson.Get(json, "result.events.tx\\.hash.0")
|
||||
|
||||
if targetChain.Exists() && tokenChain.Exists() && tokenDecimals.Exists() && token.Exists() &&
|
||||
sender.Exists() && recipient.Exists() && amount.Exists() && amount.Exists() && nonce.Exists() && txHash.Exists() {
|
||||
|
||||
logger.Info("Token lock detected on Terra: ",
|
||||
zap.String("txHash", txHash.String()),
|
||||
zap.String("targetChain", targetChain.String()),
|
||||
zap.String("tokenChain", tokenChain.String()),
|
||||
zap.String("tokenDecimals", tokenDecimals.String()),
|
||||
zap.String("token", token.String()),
|
||||
zap.String("sender", sender.String()),
|
||||
zap.String("recipient", recipient.String()),
|
||||
zap.String("amount", amount.String()),
|
||||
zap.String("nonce", nonce.String()))
|
||||
|
||||
senderAddress, err := StringToAddress(sender.String())
|
||||
if err != nil {
|
||||
logger.Error("cannot decode hex ", zap.String("value", sender.String()))
|
||||
continue
|
||||
}
|
||||
recipientAddress, err := StringToAddress(recipient.String())
|
||||
if err != nil {
|
||||
logger.Error("cannot decode hex ", zap.String("value", recipient.String()))
|
||||
continue
|
||||
}
|
||||
tokenAddress, err := StringToAddress(token.String())
|
||||
if err != nil {
|
||||
logger.Error("cannot decode hex ", zap.String("value", token.String()))
|
||||
continue
|
||||
}
|
||||
txHashValue, err := StringToHash(txHash.String())
|
||||
if err != nil {
|
||||
logger.Error("cannot decode hex ", zap.String("value", txHash.String()))
|
||||
continue
|
||||
}
|
||||
lock := &common.ChainLock{
|
||||
TxHash: txHashValue,
|
||||
Timestamp: time.Now(), // No timestamp available, consider adding it into transaction logs or request additionally from the blockchain
|
||||
Nonce: uint32(nonce.Uint()),
|
||||
SourceAddress: senderAddress,
|
||||
TargetAddress: recipientAddress,
|
||||
SourceChain: vaa.ChainIDTerra,
|
||||
TargetChain: vaa.ChainID(uint8(targetChain.Uint())),
|
||||
TokenChain: vaa.ChainID(uint8(tokenChain.Uint())),
|
||||
TokenAddress: tokenAddress,
|
||||
TokenDecimals: uint8(tokenDecimals.Uint()),
|
||||
Amount: new(big.Int).SetUint64(amount.Uint()),
|
||||
}
|
||||
e.lockChan <- lock
|
||||
}
|
||||
|
||||
// Query and report guardian set status
|
||||
requestURL := fmt.Sprintf("%s/wasm/contracts/%s/store?query_msg={\"guardian_set_info\":{}}", e.urlLCD, e.bridge)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)
|
||||
if err != nil {
|
||||
logger.Error("query guardian set request error", zap.Error(err))
|
||||
errC <- err
|
||||
return
|
||||
}
|
||||
client := &http.Client{
|
||||
Timeout: time.Second * 15,
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
logger.Error("query guardian set response error", zap.Error(err))
|
||||
errC <- err
|
||||
return
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logger.Error("query guardian set error", zap.Error(err))
|
||||
errC <- err
|
||||
resp.Body.Close()
|
||||
return
|
||||
}
|
||||
json = string(body)
|
||||
guardianSetIndex := gjson.Get(json, "result.guardian_set_index")
|
||||
addresses := gjson.Get(json, "result.addresses.#.bytes")
|
||||
|
||||
logger.Debug("Current guardian set on Terra: ",
|
||||
zap.Any("guardianSetIndex", guardianSetIndex),
|
||||
zap.Any("addresses", addresses))
|
||||
|
||||
resp.Body.Close()
|
||||
|
||||
// Do not report it since ETH guardians are the source of truth
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
|
||||
if err != nil {
|
||||
logger.Error("error on closing socket ", zap.Error(err))
|
||||
}
|
||||
return ctx.Err()
|
||||
case err := <-errC:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// StringToAddress convert string into address
|
||||
func StringToAddress(value string) (vaa.Address, error) {
|
||||
var address vaa.Address
|
||||
res, err := hex.DecodeString(value)
|
||||
if err != nil {
|
||||
return address, err
|
||||
}
|
||||
copy(address[:], res)
|
||||
return address, nil
|
||||
}
|
||||
|
||||
// StringToHash convert string into transaction hash
|
||||
func StringToHash(value string) (eth_common.Hash, error) {
|
||||
var hash eth_common.Hash
|
||||
res, err := hex.DecodeString(value)
|
||||
if err != nil {
|
||||
return hash, err
|
||||
}
|
||||
copy(hash[:], res)
|
||||
return hash, nil
|
||||
}
|
|
@ -110,6 +110,8 @@ const (
|
|||
ChainIDSolana = 1
|
||||
// ChainIDEthereum is the ChainID of Ethereum
|
||||
ChainIDEthereum = 2
|
||||
// ChainIDTerra is the ChainID of Terra
|
||||
ChainIDTerra = 3
|
||||
|
||||
minVAALength = 1 + 4 + 52 + 4 + 1 + 1
|
||||
SupportedVAAVersion = 0x01
|
||||
|
|
|
@ -41,6 +41,9 @@ spec:
|
|||
containers:
|
||||
- name: guardiand
|
||||
image: guardiand-image
|
||||
env:
|
||||
- name: TERRA_FEE_PAYER
|
||||
value: "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius"
|
||||
command:
|
||||
# Uncomment this to enable in-place debugging using dlv
|
||||
# (not suitable for regular development since the process will no longer restart on its own)
|
||||
|
@ -57,6 +60,17 @@ spec:
|
|||
- bridge
|
||||
- --ethRPC
|
||||
- ws://eth-devnet:8545
|
||||
- --terra
|
||||
- --terraWS
|
||||
- ws://terra-terrad:26657/websocket
|
||||
- --terraLCD
|
||||
- http://terra-lcd:1317
|
||||
- --terraChainID
|
||||
- localterra
|
||||
- --terraContract
|
||||
- terra174kgn5rtw4kf6f938wm7kwh70h2v4vcfd26jlc
|
||||
- --terraFeePayer
|
||||
- $(TERRA_FEE_PAYER)
|
||||
- --agentRPC
|
||||
- localhost:9000
|
||||
- --ethConfirmations
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
|||
[workspace]
|
||||
members = ["contracts/cw20-wrapped", "contracts/wormhole"]
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
debug = false
|
||||
rpath = false
|
||||
lto = true
|
||||
debug-assertions = false
|
||||
codegen-units = 1
|
||||
panic = 'abort'
|
||||
incremental = false
|
||||
overflow-checks = true
|
|
@ -0,0 +1,6 @@
|
|||
# Smaller environment only with terra and no bridge
|
||||
|
||||
k8s_yaml("../devnet/terra-devnet.yaml")
|
||||
|
||||
k8s_resource("terra-lcd")
|
||||
k8s_resource("terra-terrad")
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
[alias]
|
||||
wasm = "build --release --target wasm32-unknown-unknown"
|
||||
wasm-debug = "build --target wasm32-unknown-unknown"
|
||||
unit-test = "test --lib --features backtraces"
|
||||
integration-test = "test --test integration"
|
|
@ -0,0 +1,26 @@
|
|||
[package]
|
||||
name = "cw20-wrapped"
|
||||
version = "0.1.0"
|
||||
authors = ["Yuriy Savchenko <yuriy.savchenko@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "Wrapped CW20 token contract"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
backtraces = ["cosmwasm-std/backtraces"]
|
||||
# use library feature to disable all init/handle/query exports
|
||||
library = []
|
||||
|
||||
[dependencies]
|
||||
cosmwasm-std = { version = "0.10.0" }
|
||||
cosmwasm-storage = { version = "0.10.0" }
|
||||
schemars = "0.7"
|
||||
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
|
||||
cw20 = "0.2.0"
|
||||
cw20-base = { version = "0.2.0", features = ["library"] }
|
||||
thiserror = { version = "1.0.20" }
|
||||
|
||||
[dev-dependencies]
|
||||
cosmwasm-vm = { version = "0.10.0", default-features = false, features = ["default-cranelift"] }
|
|
@ -0,0 +1,396 @@
|
|||
use cosmwasm_std::{
|
||||
log, to_binary, Api, Binary, CosmosMsg, Env, Extern, HandleResponse, HumanAddr, InitResponse,
|
||||
Querier, StdError, StdResult, Storage, Uint128, WasmMsg,
|
||||
};
|
||||
|
||||
use cw20_base::allowances::{
|
||||
handle_burn_from, handle_decrease_allowance, handle_increase_allowance, handle_send_from,
|
||||
handle_transfer_from, query_allowance,
|
||||
};
|
||||
use cw20_base::contract::{
|
||||
handle_mint, handle_send, handle_transfer, query_balance, query_token_info,
|
||||
};
|
||||
use cw20_base::state::{balances, token_info, MinterData, TokenInfo};
|
||||
|
||||
use crate::msg::{HandleMsg, InitMsg, QueryMsg, WrappedAssetInfoResponse};
|
||||
use crate::state::{wrapped_asset_info, wrapped_asset_info_read, WrappedAssetInfo};
|
||||
use std::string::String;
|
||||
|
||||
pub fn init<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
msg: InitMsg,
|
||||
) -> StdResult<InitResponse> {
|
||||
// store token info using cw20-base format
|
||||
let data = TokenInfo {
|
||||
name: String::from("Wormhole Wrapped"),
|
||||
symbol: String::from("WWT"),
|
||||
decimals: msg.decimals,
|
||||
total_supply: Uint128(0),
|
||||
// set creator as minter
|
||||
mint: Some(MinterData {
|
||||
minter: deps.api.canonical_address(&env.message.sender)?,
|
||||
cap: None,
|
||||
}),
|
||||
};
|
||||
token_info(&mut deps.storage).save(&data)?;
|
||||
|
||||
// save wrapped asset info
|
||||
let data = WrappedAssetInfo {
|
||||
asset_chain: msg.asset_chain,
|
||||
asset_address: msg.asset_address,
|
||||
bridge: deps.api.canonical_address(&env.message.sender)?,
|
||||
};
|
||||
wrapped_asset_info(&mut deps.storage).save(&data)?;
|
||||
|
||||
if let Some(mint_info) = msg.mint {
|
||||
handle_mint(deps, env, mint_info.recipient, mint_info.amount)?;
|
||||
}
|
||||
|
||||
if let Some(hook) = msg.init_hook {
|
||||
Ok(InitResponse {
|
||||
messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
|
||||
contract_addr: hook.contract_addr,
|
||||
msg: hook.msg,
|
||||
send: vec![],
|
||||
})],
|
||||
log: vec![],
|
||||
})
|
||||
} else {
|
||||
Ok(InitResponse::default())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
msg: HandleMsg,
|
||||
) -> StdResult<HandleResponse> {
|
||||
match msg {
|
||||
// these all come from cw20-base to implement the cw20 standard
|
||||
HandleMsg::Transfer { recipient, amount } => {
|
||||
Ok(handle_transfer(deps, env, recipient, amount)?)
|
||||
}
|
||||
HandleMsg::Burn { account, amount } => Ok(handle_burn_wrapped(deps, env, account, amount)?),
|
||||
HandleMsg::Send {
|
||||
contract,
|
||||
amount,
|
||||
msg,
|
||||
} => Ok(handle_send(deps, env, contract, amount, msg)?),
|
||||
HandleMsg::Mint { recipient, amount } => handle_mint_wrapped(deps, env, recipient, amount),
|
||||
HandleMsg::IncreaseAllowance {
|
||||
spender,
|
||||
amount,
|
||||
expires,
|
||||
} => Ok(handle_increase_allowance(
|
||||
deps, env, spender, amount, expires,
|
||||
)?),
|
||||
HandleMsg::DecreaseAllowance {
|
||||
spender,
|
||||
amount,
|
||||
expires,
|
||||
} => Ok(handle_decrease_allowance(
|
||||
deps, env, spender, amount, expires,
|
||||
)?),
|
||||
HandleMsg::TransferFrom {
|
||||
owner,
|
||||
recipient,
|
||||
amount,
|
||||
} => Ok(handle_transfer_from(deps, env, owner, recipient, amount)?),
|
||||
HandleMsg::BurnFrom { owner, amount } => Ok(handle_burn_from(deps, env, owner, amount)?),
|
||||
HandleMsg::SendFrom {
|
||||
owner,
|
||||
contract,
|
||||
amount,
|
||||
msg,
|
||||
} => Ok(handle_send_from(deps, env, owner, contract, amount, msg)?),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_burn_wrapped<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
account: HumanAddr,
|
||||
amount: Uint128,
|
||||
) -> StdResult<HandleResponse> {
|
||||
// Only bridge can burn
|
||||
let wrapped_info = wrapped_asset_info_read(&deps.storage).load()?;
|
||||
if wrapped_info.bridge != deps.api.canonical_address(&env.message.sender)? {
|
||||
return Err(StdError::unauthorized());
|
||||
}
|
||||
|
||||
// Copy of CW20-base handle_burn, but burning from account sent with parameters, not from sender
|
||||
if amount == Uint128::zero() {
|
||||
return Err(StdError::generic_err("Invalid zero amount"));
|
||||
}
|
||||
|
||||
let burn_from_raw = deps.api.canonical_address(&account)?;
|
||||
|
||||
// lower balance
|
||||
let mut accounts = balances(&mut deps.storage);
|
||||
accounts.update(burn_from_raw.as_slice(), |balance: Option<Uint128>| {
|
||||
balance.unwrap_or_default() - amount
|
||||
})?;
|
||||
// reduce total_supply
|
||||
token_info(&mut deps.storage).update(|mut info| {
|
||||
info.total_supply = (info.total_supply - amount)?;
|
||||
Ok(info)
|
||||
})?;
|
||||
|
||||
let res = HandleResponse {
|
||||
messages: vec![],
|
||||
log: vec![
|
||||
log("action", "burn"),
|
||||
log("from", account),
|
||||
log("amount", amount),
|
||||
],
|
||||
data: None,
|
||||
};
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn handle_mint_wrapped<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
recipient: HumanAddr,
|
||||
amount: Uint128,
|
||||
) -> StdResult<HandleResponse> {
|
||||
// Only bridge can mint
|
||||
let wrapped_info = wrapped_asset_info_read(&deps.storage).load()?;
|
||||
if wrapped_info.bridge != deps.api.canonical_address(&env.message.sender)? {
|
||||
return Err(StdError::unauthorized());
|
||||
}
|
||||
|
||||
return Ok(handle_mint(deps, env, recipient, amount)?);
|
||||
}
|
||||
|
||||
pub fn query<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &Extern<S, A, Q>,
|
||||
msg: QueryMsg,
|
||||
) -> StdResult<Binary> {
|
||||
match msg {
|
||||
QueryMsg::WrappedAssetInfo {} => to_binary(&query_wrapped_asset_info(deps)?),
|
||||
// inherited from cw20-base
|
||||
QueryMsg::TokenInfo {} => to_binary(&query_token_info(deps)?),
|
||||
QueryMsg::Balance { address } => to_binary(&query_balance(deps, address)?),
|
||||
QueryMsg::Allowance { owner, spender } => {
|
||||
to_binary(&query_allowance(deps, owner, spender)?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query_wrapped_asset_info<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &Extern<S, A, Q>,
|
||||
) -> StdResult<WrappedAssetInfoResponse> {
|
||||
let info = wrapped_asset_info_read(&deps.storage).load()?;
|
||||
let res = WrappedAssetInfoResponse {
|
||||
asset_chain: info.asset_chain,
|
||||
asset_address: info.asset_address,
|
||||
bridge: deps.api.human_address(&info.bridge)?,
|
||||
};
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use cosmwasm_std::testing::{mock_dependencies, mock_env};
|
||||
use cosmwasm_std::HumanAddr;
|
||||
use cw20::TokenInfoResponse;
|
||||
|
||||
const CANONICAL_LENGTH: usize = 20;
|
||||
|
||||
fn get_balance<S: Storage, A: Api, Q: Querier, T: Into<HumanAddr>>(
|
||||
deps: &Extern<S, A, Q>,
|
||||
address: T,
|
||||
) -> Uint128 {
|
||||
query_balance(&deps, address.into()).unwrap().balance
|
||||
}
|
||||
|
||||
fn do_init<S: Storage, A: Api, Q: Querier>(deps: &mut Extern<S, A, Q>, creator: &HumanAddr) {
|
||||
let init_msg = InitMsg {
|
||||
asset_chain: 1,
|
||||
asset_address: vec![1; 32],
|
||||
decimals: 10,
|
||||
mint: None,
|
||||
init_hook: None,
|
||||
};
|
||||
let env = mock_env(creator, &[]);
|
||||
let res = init(deps, env, init_msg).unwrap();
|
||||
assert_eq!(0, res.messages.len());
|
||||
|
||||
assert_eq!(
|
||||
query_token_info(&deps).unwrap(),
|
||||
TokenInfoResponse {
|
||||
name: "Wormhole Wrapped".to_string(),
|
||||
symbol: "WWT".to_string(),
|
||||
decimals: 10,
|
||||
total_supply: Uint128::from(0u128),
|
||||
}
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
query_wrapped_asset_info(&deps).unwrap(),
|
||||
WrappedAssetInfoResponse {
|
||||
asset_chain: 1,
|
||||
asset_address: vec![1; 32],
|
||||
bridge: creator.clone(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
fn do_init_and_mint<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
creator: &HumanAddr,
|
||||
mint_to: &HumanAddr,
|
||||
amount: Uint128,
|
||||
) {
|
||||
do_init(deps, creator);
|
||||
|
||||
let msg = HandleMsg::Mint {
|
||||
recipient: mint_to.clone(),
|
||||
amount,
|
||||
};
|
||||
|
||||
let env = mock_env(&creator, &[]);
|
||||
let res = handle(deps, env, msg.clone()).unwrap();
|
||||
assert_eq!(0, res.messages.len());
|
||||
assert_eq!(get_balance(deps, mint_to), amount);
|
||||
|
||||
assert_eq!(
|
||||
query_token_info(&deps).unwrap(),
|
||||
TokenInfoResponse {
|
||||
name: "Wormhole Wrapped".to_string(),
|
||||
symbol: "WWT".to_string(),
|
||||
decimals: 10,
|
||||
total_supply: amount,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_mint_by_minter() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
let minter = HumanAddr::from("minter");
|
||||
let recipient = HumanAddr::from("recipient");
|
||||
let amount = Uint128(222_222_222);
|
||||
do_init_and_mint(&mut deps, &minter, &recipient, amount);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn others_cannot_mint() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
let minter = HumanAddr::from("minter");
|
||||
let recipient = HumanAddr::from("recipient");
|
||||
do_init(&mut deps, &minter);
|
||||
|
||||
let amount = Uint128(222_222_222);
|
||||
let msg = HandleMsg::Mint {
|
||||
recipient: recipient.clone(),
|
||||
amount,
|
||||
};
|
||||
|
||||
let other_address = HumanAddr::from("other");
|
||||
let env = mock_env(&other_address, &[]);
|
||||
let res = handle(&mut deps, env, msg);
|
||||
assert_eq!(
|
||||
format!("{}", res.unwrap_err()),
|
||||
format!("{}", crate::error::ContractError::Unauthorized {})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_burn_by_minter() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
let minter = HumanAddr::from("minter");
|
||||
let recipient = HumanAddr::from("recipient");
|
||||
let amount = Uint128(222_222_222);
|
||||
do_init_and_mint(&mut deps, &minter, &recipient, amount);
|
||||
|
||||
let amount_to_burn = Uint128(222_222_221);
|
||||
let msg = HandleMsg::Burn {
|
||||
account: recipient.clone(),
|
||||
amount: amount_to_burn,
|
||||
};
|
||||
|
||||
let env = mock_env(&minter, &[]);
|
||||
let res = handle(&mut deps, env, msg.clone()).unwrap();
|
||||
assert_eq!(0, res.messages.len());
|
||||
assert_eq!(get_balance(&deps, recipient), Uint128(1));
|
||||
|
||||
assert_eq!(
|
||||
query_token_info(&deps).unwrap(),
|
||||
TokenInfoResponse {
|
||||
name: "Wormhole Wrapped".to_string(),
|
||||
symbol: "WWT".to_string(),
|
||||
decimals: 10,
|
||||
total_supply: Uint128(1),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn others_cannot_burn() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
let minter = HumanAddr::from("minter");
|
||||
let recipient = HumanAddr::from("recipient");
|
||||
let amount = Uint128(222_222_222);
|
||||
do_init_and_mint(&mut deps, &minter, &recipient, amount);
|
||||
|
||||
let amount_to_burn = Uint128(222_222_221);
|
||||
let msg = HandleMsg::Burn {
|
||||
account: recipient.clone(),
|
||||
amount: amount_to_burn,
|
||||
};
|
||||
|
||||
let env = mock_env(&recipient, &[]);
|
||||
let res = handle(&mut deps, env, msg.clone());
|
||||
assert_eq!(
|
||||
format!("{}", res.unwrap_err()),
|
||||
format!("{}", crate::error::ContractError::Unauthorized {})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transfer_balance_success() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
let minter = HumanAddr::from("minter");
|
||||
let owner = HumanAddr::from("owner");
|
||||
let amount_initial = Uint128(222_222_222);
|
||||
do_init_and_mint(&mut deps, &minter, &owner, amount_initial);
|
||||
|
||||
// Transfer
|
||||
let recipient = HumanAddr::from("recipient");
|
||||
let amount_transfer = Uint128(222_222);
|
||||
let msg = HandleMsg::Transfer {
|
||||
recipient: recipient.clone(),
|
||||
amount: amount_transfer,
|
||||
};
|
||||
|
||||
let env = mock_env(&owner, &[]);
|
||||
let res = handle(&mut deps, env, msg.clone()).unwrap();
|
||||
assert_eq!(0, res.messages.len());
|
||||
assert_eq!(get_balance(&deps, owner), Uint128(222_000_000));
|
||||
assert_eq!(get_balance(&deps, recipient), amount_transfer);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transfer_balance_not_enough() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
let minter = HumanAddr::from("minter");
|
||||
let owner = HumanAddr::from("owner");
|
||||
let amount_initial = Uint128(222_221);
|
||||
do_init_and_mint(&mut deps, &minter, &owner, amount_initial);
|
||||
|
||||
// Transfer
|
||||
let recipient = HumanAddr::from("recipient");
|
||||
let amount_transfer = Uint128(222_222);
|
||||
let msg = HandleMsg::Transfer {
|
||||
recipient: recipient.clone(),
|
||||
amount: amount_transfer,
|
||||
};
|
||||
|
||||
let env = mock_env(&owner, &[]);
|
||||
let _ = handle(&mut deps, env, msg.clone()).unwrap_err(); // Will panic if no error
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
use cosmwasm_std::StdError;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ContractError {
|
||||
// CW20 errors
|
||||
#[error("{0}")]
|
||||
Std(#[from] StdError),
|
||||
|
||||
#[error("Unauthorized")]
|
||||
Unauthorized {},
|
||||
|
||||
#[error("Cannot set to own account")]
|
||||
CannotSetOwnAccount {},
|
||||
|
||||
#[error("Invalid zero amount")]
|
||||
InvalidZeroAmount {},
|
||||
|
||||
#[error("Allowance is expired")]
|
||||
Expired {},
|
||||
|
||||
#[error("No allowance for this account")]
|
||||
NoAllowance {},
|
||||
|
||||
#[error("Minting cannot exceed the cap")]
|
||||
CannotExceedCap {},
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
pub mod contract;
|
||||
mod error;
|
||||
pub mod msg;
|
||||
pub mod state;
|
||||
|
||||
pub use crate::error::ContractError;
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", not(feature = "library")))]
|
||||
cosmwasm_std::create_entry_points!(contract);
|
|
@ -0,0 +1,110 @@
|
|||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cosmwasm_std::{Binary, HumanAddr, Uint128};
|
||||
use cw20::Expiration;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct InitMsg {
|
||||
pub asset_chain: u8,
|
||||
pub asset_address: Vec<u8>,
|
||||
pub decimals: u8,
|
||||
pub mint: Option<InitMint>,
|
||||
pub init_hook: Option<InitHook>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct InitHook {
|
||||
pub msg: Binary,
|
||||
pub contract_addr: HumanAddr,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct InitMint {
|
||||
pub recipient: HumanAddr,
|
||||
pub amount: Uint128,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HandleMsg {
|
||||
/// Implements CW20. Transfer is a base message to move tokens to another account without triggering actions
|
||||
Transfer {
|
||||
recipient: HumanAddr,
|
||||
amount: Uint128,
|
||||
},
|
||||
/// Slightly different than CW20. Burn is a base message to destroy tokens forever
|
||||
Burn { account: HumanAddr, amount: Uint128 },
|
||||
/// Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action
|
||||
/// on the receiving contract.
|
||||
Send {
|
||||
contract: HumanAddr,
|
||||
amount: Uint128,
|
||||
msg: Option<Binary>,
|
||||
},
|
||||
/// Implements CW20 "mintable" extension. If authorized, creates amount new tokens
|
||||
/// and adds to the recipient balance.
|
||||
Mint {
|
||||
recipient: HumanAddr,
|
||||
amount: Uint128,
|
||||
},
|
||||
/// Implements CW20 "approval" extension. Allows spender to access an additional amount tokens
|
||||
/// from the owner's (env.sender) account. If expires is Some(), overwrites current allowance
|
||||
/// expiration with this one.
|
||||
IncreaseAllowance {
|
||||
spender: HumanAddr,
|
||||
amount: Uint128,
|
||||
expires: Option<Expiration>,
|
||||
},
|
||||
/// Implements CW20 "approval" extension. Lowers the spender's access of tokens
|
||||
/// from the owner's (env.sender) account by amount. If expires is Some(), overwrites current
|
||||
/// allowance expiration with this one.
|
||||
DecreaseAllowance {
|
||||
spender: HumanAddr,
|
||||
amount: Uint128,
|
||||
expires: Option<Expiration>,
|
||||
},
|
||||
/// Implements CW20 "approval" extension. Transfers amount tokens from owner -> recipient
|
||||
/// if `env.sender` has sufficient pre-approval.
|
||||
TransferFrom {
|
||||
owner: HumanAddr,
|
||||
recipient: HumanAddr,
|
||||
amount: Uint128,
|
||||
},
|
||||
/// Implements CW20 "approval" extension. Sends amount tokens from owner -> contract
|
||||
/// if `env.sender` has sufficient pre-approval.
|
||||
SendFrom {
|
||||
owner: HumanAddr,
|
||||
contract: HumanAddr,
|
||||
amount: Uint128,
|
||||
msg: Option<Binary>,
|
||||
},
|
||||
/// Implements CW20 "approval" extension. Destroys tokens forever
|
||||
BurnFrom { owner: HumanAddr, amount: Uint128 },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum QueryMsg {
|
||||
// Generic information about the wrapped asset
|
||||
WrappedAssetInfo {},
|
||||
/// Implements CW20. Returns the current balance of the given address, 0 if unset.
|
||||
Balance {
|
||||
address: HumanAddr,
|
||||
},
|
||||
/// Implements CW20. Returns metadata on the contract - name, decimals, supply, etc.
|
||||
TokenInfo {},
|
||||
/// Implements CW20 "allowance" extension.
|
||||
/// Returns how much spender can use from owner account, 0 if unset.
|
||||
Allowance {
|
||||
owner: HumanAddr,
|
||||
spender: HumanAddr,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct WrappedAssetInfoResponse {
|
||||
pub asset_chain: u8, // Asset chain id
|
||||
pub asset_address: Vec<u8>, // Asset smart contract address in the original chain
|
||||
pub bridge: HumanAddr, // Bridge address, authorized to mint and burn wrapped tokens
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cosmwasm_std::{CanonicalAddr, ReadonlyStorage, Storage};
|
||||
use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton};
|
||||
|
||||
pub const KEY_WRAPPED_ASSET: &[u8] = b"wrappedAsset";
|
||||
|
||||
// Created at initialization and reference original asset and bridge address
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct WrappedAssetInfo {
|
||||
pub asset_chain: u8, // Asset chain id
|
||||
pub asset_address: Vec<u8>, // Asset smart contract address on the original chain
|
||||
pub bridge: CanonicalAddr, // Bridge address, authorized to mint and burn wrapped tokens
|
||||
}
|
||||
|
||||
pub fn wrapped_asset_info<S: Storage>(storage: &mut S) -> Singleton<S, WrappedAssetInfo> {
|
||||
singleton(storage, KEY_WRAPPED_ASSET)
|
||||
}
|
||||
|
||||
pub fn wrapped_asset_info_read<S: ReadonlyStorage>(
|
||||
storage: &S,
|
||||
) -> ReadonlySingleton<S, WrappedAssetInfo> {
|
||||
singleton_read(storage, KEY_WRAPPED_ASSET)
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
static WASM: &[u8] =
|
||||
include_bytes!("../../../target/wasm32-unknown-unknown/release/cw20_wrapped.wasm");
|
||||
|
||||
use cosmwasm_std::{
|
||||
from_slice, Env, HandleResponse, HandleResult, HumanAddr, InitResponse, Uint128,
|
||||
};
|
||||
use cosmwasm_storage::to_length_prefixed;
|
||||
use cosmwasm_vm::testing::{
|
||||
handle, init, mock_env, mock_instance, query, MockApi, MockQuerier, MockStorage,
|
||||
};
|
||||
use cosmwasm_vm::{Api, Instance, Storage};
|
||||
use cw20_wrapped::msg::{HandleMsg, InitMsg, QueryMsg};
|
||||
use cw20_wrapped::state::WrappedAssetInfo;
|
||||
use cw20_wrapped::state::KEY_WRAPPED_ASSET;
|
||||
use cw20_wrapped::ContractError;
|
||||
|
||||
enum TestAddress {
|
||||
INITIALIZER,
|
||||
RECIPIENT,
|
||||
SENDER,
|
||||
}
|
||||
|
||||
impl TestAddress {
|
||||
fn value(&self) -> HumanAddr {
|
||||
match self {
|
||||
TestAddress::INITIALIZER => HumanAddr::from("addr0000"),
|
||||
TestAddress::RECIPIENT => HumanAddr::from("addr2222"),
|
||||
TestAddress::SENDER => HumanAddr::from("addr3333"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mock_env_height(signer: &HumanAddr, height: u64, time: u64) -> Env {
|
||||
let mut env = mock_env(signer, &[]);
|
||||
env.block.height = height;
|
||||
env.block.time = time;
|
||||
env
|
||||
}
|
||||
|
||||
fn get_wrapped_asset_info<S: Storage>(storage: &S) -> WrappedAssetInfo {
|
||||
let key = to_length_prefixed(KEY_WRAPPED_ASSET);
|
||||
let data = storage
|
||||
.get(&key)
|
||||
.0
|
||||
.expect("error getting data")
|
||||
.expect("data should exist");
|
||||
from_slice(&data).expect("invalid data")
|
||||
}
|
||||
|
||||
fn do_init(height: u64) -> Instance<MockStorage, MockApi, MockQuerier> {
|
||||
let mut deps = mock_instance(WASM, &[]);
|
||||
let init_msg = InitMsg {
|
||||
asset_chain: 1,
|
||||
asset_address: vec![1; 32],
|
||||
decimals: 10,
|
||||
mint: None,
|
||||
init_hook: None,
|
||||
};
|
||||
let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0);
|
||||
let res: InitResponse = init(&mut deps, env, init_msg).unwrap();
|
||||
assert_eq!(0, res.messages.len());
|
||||
|
||||
// query the store directly
|
||||
let api = deps.api;
|
||||
deps.with_storage(|storage| {
|
||||
assert_eq!(
|
||||
get_wrapped_asset_info(storage),
|
||||
WrappedAssetInfo {
|
||||
asset_chain: 1,
|
||||
asset_address: vec![1; 32],
|
||||
bridge: api.canonical_address(&TestAddress::INITIALIZER.value()).0?,
|
||||
}
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
deps
|
||||
}
|
||||
|
||||
fn do_mint(
|
||||
deps: &mut Instance<MockStorage, MockApi, MockQuerier>,
|
||||
height: u64,
|
||||
recipient: &HumanAddr,
|
||||
amount: &Uint128,
|
||||
) {
|
||||
let mint_msg = HandleMsg::Mint {
|
||||
recipient: recipient.clone(),
|
||||
amount: amount.clone(),
|
||||
};
|
||||
let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0);
|
||||
let handle_response: HandleResponse = handle(deps, env, mint_msg).unwrap();
|
||||
assert_eq!(0, handle_response.messages.len());
|
||||
}
|
||||
|
||||
fn do_transfer(
|
||||
deps: &mut Instance<MockStorage, MockApi, MockQuerier>,
|
||||
height: u64,
|
||||
sender: &HumanAddr,
|
||||
recipient: &HumanAddr,
|
||||
amount: &Uint128,
|
||||
) {
|
||||
let transfer_msg = HandleMsg::Transfer {
|
||||
recipient: recipient.clone(),
|
||||
amount: amount.clone(),
|
||||
};
|
||||
let env = mock_env_height(sender, height, 0);
|
||||
let handle_response: HandleResponse = handle(deps, env, transfer_msg).unwrap();
|
||||
assert_eq!(0, handle_response.messages.len());
|
||||
}
|
||||
|
||||
fn check_balance(
|
||||
deps: &mut Instance<MockStorage, MockApi, MockQuerier>,
|
||||
address: &HumanAddr,
|
||||
amount: &Uint128,
|
||||
) {
|
||||
let query_response = query(
|
||||
deps,
|
||||
QueryMsg::Balance {
|
||||
address: address.clone(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
query_response.as_slice(),
|
||||
format!("{{\"balance\":\"{}\"}}", amount.u128()).as_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
fn check_token_details(deps: &mut Instance<MockStorage, MockApi, MockQuerier>, supply: &Uint128) {
|
||||
let query_response = query(deps, QueryMsg::TokenInfo {}).unwrap();
|
||||
assert_eq!(
|
||||
query_response.as_slice(),
|
||||
format!(
|
||||
"{{\"name\":\"Wormhole Wrapped\",\
|
||||
\"symbol\":\"WWT\",\
|
||||
\"decimals\":10,\
|
||||
\"total_supply\":\"{}\"}}",
|
||||
supply.u128()
|
||||
)
|
||||
.as_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
fn format_array(data: &Vec<u8>) -> String {
|
||||
let mut result = String::new();
|
||||
|
||||
for num in &data[0..data.len() - 1] {
|
||||
result.push_str(&num.to_string());
|
||||
result.push_str(",");
|
||||
}
|
||||
result.push_str(&data[data.len() - 1].to_string());
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_works() {
|
||||
let mut deps = do_init(111);
|
||||
check_token_details(&mut deps, &Uint128(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn query_works() {
|
||||
let mut deps = do_init(111);
|
||||
|
||||
let query_response = query(&mut deps, QueryMsg::WrappedAssetInfo {}).unwrap();
|
||||
assert_eq!(
|
||||
query_response.as_slice(),
|
||||
format!(
|
||||
"{{\"asset_chain\":1,\
|
||||
\"asset_address\":[{}],\
|
||||
\"bridge\":\"{}\"}}",
|
||||
format_array(&vec![1; 32]),
|
||||
TestAddress::INITIALIZER.value().as_str()
|
||||
)
|
||||
.as_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mint_works() {
|
||||
let mut deps = do_init(111);
|
||||
|
||||
do_mint(
|
||||
&mut deps,
|
||||
112,
|
||||
&TestAddress::RECIPIENT.value(),
|
||||
&Uint128(123_123_123),
|
||||
);
|
||||
|
||||
check_balance(
|
||||
&mut deps,
|
||||
&TestAddress::RECIPIENT.value(),
|
||||
&Uint128(123_123_123),
|
||||
);
|
||||
check_token_details(&mut deps, &Uint128(123_123_123));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn others_cannot_mint() {
|
||||
let mut deps = do_init(111);
|
||||
|
||||
let mint_msg = HandleMsg::Mint {
|
||||
recipient: TestAddress::RECIPIENT.value(),
|
||||
amount: Uint128(123_123_123),
|
||||
};
|
||||
let env = mock_env_height(&TestAddress::RECIPIENT.value(), 112, 0);
|
||||
let handle_result: HandleResult<HandleResponse> = handle(&mut deps, env, mint_msg);
|
||||
assert_eq!(
|
||||
format!("{}", handle_result.unwrap_err()),
|
||||
format!("{}", ContractError::Unauthorized {})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transfer_works() {
|
||||
let mut deps = do_init(111);
|
||||
|
||||
do_mint(
|
||||
&mut deps,
|
||||
112,
|
||||
&TestAddress::SENDER.value(),
|
||||
&Uint128(123_123_123),
|
||||
);
|
||||
do_transfer(
|
||||
&mut deps,
|
||||
113,
|
||||
&TestAddress::SENDER.value(),
|
||||
&TestAddress::RECIPIENT.value(),
|
||||
&Uint128(123_123_000),
|
||||
);
|
||||
|
||||
check_balance(&mut deps, &TestAddress::SENDER.value(), &Uint128(123));
|
||||
check_balance(
|
||||
&mut deps,
|
||||
&TestAddress::RECIPIENT.value(),
|
||||
&Uint128(123_123_000),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn burn_works() {
|
||||
let mut deps = do_init(111);
|
||||
|
||||
do_mint(
|
||||
&mut deps,
|
||||
112,
|
||||
&TestAddress::RECIPIENT.value(),
|
||||
&Uint128(123_123_123),
|
||||
);
|
||||
|
||||
let burn_msg = HandleMsg::Burn {
|
||||
account: TestAddress::RECIPIENT.value(),
|
||||
amount: Uint128(123_123_000),
|
||||
};
|
||||
let env = mock_env_height(&TestAddress::INITIALIZER.value(), 113, 0);
|
||||
let handle_response: HandleResponse = handle(&mut deps, env, burn_msg).unwrap();
|
||||
assert_eq!(0, handle_response.messages.len());
|
||||
|
||||
check_balance(&mut deps, &TestAddress::RECIPIENT.value(), &Uint128(123));
|
||||
check_token_details(&mut deps, &Uint128(123));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn others_cannot_burn() {
|
||||
let mut deps = do_init(111);
|
||||
|
||||
do_mint(
|
||||
&mut deps,
|
||||
112,
|
||||
&TestAddress::RECIPIENT.value(),
|
||||
&Uint128(123_123_123),
|
||||
);
|
||||
|
||||
let burn_msg = HandleMsg::Burn {
|
||||
account: TestAddress::RECIPIENT.value(),
|
||||
amount: Uint128(123_123_000),
|
||||
};
|
||||
let env = mock_env_height(&TestAddress::RECIPIENT.value(), 113, 0);
|
||||
let handle_result: HandleResult<HandleResponse> = handle(&mut deps, env, burn_msg);
|
||||
assert_eq!(
|
||||
format!("{}", handle_result.unwrap_err()),
|
||||
format!("{}", ContractError::Unauthorized {})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_burn_more_than_available() {
|
||||
let mut deps = do_init(111);
|
||||
|
||||
do_mint(
|
||||
&mut deps,
|
||||
112,
|
||||
&TestAddress::RECIPIENT.value(),
|
||||
&Uint128(123_123_123),
|
||||
);
|
||||
|
||||
let burn_msg = HandleMsg::Burn {
|
||||
account: TestAddress::RECIPIENT.value(),
|
||||
amount: Uint128(123_123_124),
|
||||
};
|
||||
let env = mock_env_height(&TestAddress::INITIALIZER.value(), 113, 0);
|
||||
let handle_result: HandleResult<HandleResponse> = handle(&mut deps, env, burn_msg);
|
||||
assert_eq!(
|
||||
format!("{}", handle_result.unwrap_err()),
|
||||
"Cannot subtract 123123124 from 123123123"
|
||||
);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
[alias]
|
||||
wasm = "build --release --target wasm32-unknown-unknown"
|
||||
wasm-debug = "build --target wasm32-unknown-unknown"
|
||||
unit-test = "test --lib --features backtraces"
|
||||
integration-test = "test --test integration"
|
|
@ -0,0 +1,30 @@
|
|||
[package]
|
||||
name = "wormhole"
|
||||
version = "0.1.0"
|
||||
authors = ["Yuriy Savchenko <yuriy.savchenko@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "Wormhole contract"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
backtraces = ["cosmwasm-std/backtraces"]
|
||||
# use library feature to disable all init/handle/query exports
|
||||
library = []
|
||||
|
||||
[dependencies]
|
||||
cosmwasm-std = { version = "0.10.0" }
|
||||
cosmwasm-storage = { version = "0.10.0" }
|
||||
schemars = "0.7"
|
||||
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
|
||||
cw20 = "0.2.2"
|
||||
cw20-base = { version = "0.2.2", features = ["library"] }
|
||||
cw20-wrapped = { path = "../cw20-wrapped", features = ["library"] }
|
||||
thiserror = { version = "1.0.20" }
|
||||
k256 = { version = "0.5.9", default-features = false, features = ["ecdsa"] }
|
||||
sha3 = { version = "0.9.1", default-features = false }
|
||||
hex = "0.4.2"
|
||||
|
||||
[dev-dependencies]
|
||||
cosmwasm-vm = { version = "0.10.0", default-features = false, features = ["default-cranelift"] }
|
|
@ -0,0 +1,43 @@
|
|||
use cosmwasm_std::CanonicalAddr;
|
||||
|
||||
pub trait ByteUtils {
|
||||
fn get_u8(&self, index: usize) -> u8;
|
||||
fn get_u32(&self, index: usize) -> u32;
|
||||
fn get_u128_be(&self, index: usize) -> u128;
|
||||
/// High 128 then low 128
|
||||
fn get_u256(&self, index: usize) -> (u128, u128);
|
||||
fn get_address(&self, index: usize) -> CanonicalAddr;
|
||||
fn get_bytes32(&self, index: usize) -> &[u8];
|
||||
}
|
||||
|
||||
impl ByteUtils for &[u8] {
|
||||
fn get_u8(&self, index: usize) -> u8 {
|
||||
self[index]
|
||||
}
|
||||
fn get_u32(&self, index: usize) -> u32 {
|
||||
let mut bytes: [u8; 32 / 8] = [0; 32 / 8];
|
||||
bytes.copy_from_slice(&self[index..index + 4]);
|
||||
u32::from_be_bytes(bytes)
|
||||
}
|
||||
fn get_u128_be(&self, index: usize) -> u128 {
|
||||
let mut bytes: [u8; 128 / 8] = [0; 128 / 8];
|
||||
bytes.copy_from_slice(&self[index..index + 128 / 8]);
|
||||
u128::from_be_bytes(bytes)
|
||||
}
|
||||
fn get_u256(&self, index: usize) -> (u128, u128) {
|
||||
(self.get_u128_be(index), self.get_u128_be(index + 128 / 8))
|
||||
}
|
||||
fn get_address(&self, index: usize) -> CanonicalAddr {
|
||||
// 32 bytes are reserved for addresses, but only the last 20 bytes are taken by the actual address
|
||||
CanonicalAddr::from(&self[index + 32 - 20..index + 32])
|
||||
}
|
||||
fn get_bytes32(&self, index: usize) -> &[u8] {
|
||||
&self[index..index + 32]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend_address_to_32(addr: &CanonicalAddr) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = vec![0; 12];
|
||||
result.extend(addr.as_slice());
|
||||
result
|
||||
}
|
|
@ -0,0 +1,723 @@
|
|||
use cosmwasm_std::{
|
||||
log, to_binary, Api, Binary, CanonicalAddr, CosmosMsg, Env, Extern, HandleResponse, HumanAddr,
|
||||
InitResponse, Querier, QueryRequest, StdResult, Storage, Uint128, WasmMsg, WasmQuery,
|
||||
};
|
||||
|
||||
use crate::byte_utils::extend_address_to_32;
|
||||
use crate::byte_utils::ByteUtils;
|
||||
use crate::error::ContractError;
|
||||
use crate::msg::{GuardianSetInfoResponse, HandleMsg, InitMsg, QueryMsg};
|
||||
use crate::state::{
|
||||
config, config_read, guardian_set_get, guardian_set_set, vaa_archive_add, vaa_archive_check,
|
||||
wrapped_asset, wrapped_asset_address, wrapped_asset_address_read, wrapped_asset_read,
|
||||
ConfigInfo, GuardianAddress, GuardianSetInfo,
|
||||
};
|
||||
|
||||
use cw20_base::msg::HandleMsg as TokenMsg;
|
||||
use cw20_base::msg::QueryMsg as TokenQuery;
|
||||
|
||||
use cw20::TokenInfoResponse;
|
||||
|
||||
use hex;
|
||||
|
||||
use cw20_wrapped::msg::HandleMsg as WrappedMsg;
|
||||
use cw20_wrapped::msg::InitMsg as WrappedInit;
|
||||
use cw20_wrapped::msg::QueryMsg as WrappedQuery;
|
||||
use cw20_wrapped::msg::{InitHook, InitMint, WrappedAssetInfoResponse};
|
||||
|
||||
use k256::ecdsa::recoverable::Id as RecoverableId;
|
||||
use k256::ecdsa::recoverable::Signature as RecoverableSignature;
|
||||
use k256::ecdsa::Signature;
|
||||
use k256::ecdsa::VerifyKey;
|
||||
use k256::EncodedPoint;
|
||||
use sha3::{Digest, Keccak256};
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
||||
// Chain ID of Terra
|
||||
const CHAIN_ID: u8 = 3;
|
||||
|
||||
pub fn init<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
msg: InitMsg,
|
||||
) -> StdResult<InitResponse> {
|
||||
// Save general wormhole info
|
||||
let state = ConfigInfo {
|
||||
guardian_set_index: 0,
|
||||
guardian_set_expirity: msg.guardian_set_expirity,
|
||||
wrapped_asset_code_id: msg.wrapped_asset_code_id,
|
||||
owner: deps.api.canonical_address(&env.message.sender)?,
|
||||
is_active: true,
|
||||
};
|
||||
config(&mut deps.storage).save(&state)?;
|
||||
|
||||
// Add initial guardian set to storage
|
||||
guardian_set_set(
|
||||
&mut deps.storage,
|
||||
state.guardian_set_index,
|
||||
&msg.initial_guardian_set,
|
||||
)?;
|
||||
|
||||
Ok(InitResponse::default())
|
||||
}
|
||||
|
||||
pub fn handle<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
msg: HandleMsg,
|
||||
) -> StdResult<HandleResponse> {
|
||||
match msg {
|
||||
HandleMsg::SubmitVAA { vaa } => handle_submit_vaa(deps, env, &vaa),
|
||||
HandleMsg::RegisterAssetHook { asset_id } => handle_register_asset(deps, env, &asset_id),
|
||||
HandleMsg::LockAssets {
|
||||
asset,
|
||||
recipient,
|
||||
amount,
|
||||
target_chain,
|
||||
nonce,
|
||||
} => handle_lock_assets(deps, env, asset, amount, recipient, target_chain, nonce),
|
||||
HandleMsg::TokensLocked {
|
||||
target_chain,
|
||||
token_chain,
|
||||
token_decimals,
|
||||
token,
|
||||
sender,
|
||||
recipient,
|
||||
amount,
|
||||
nonce,
|
||||
} => handle_tokens_locked(
|
||||
target_chain,
|
||||
token_chain,
|
||||
token_decimals,
|
||||
token,
|
||||
sender,
|
||||
recipient,
|
||||
amount,
|
||||
nonce,
|
||||
),
|
||||
HandleMsg::SetActive { is_active } => handle_set_active(deps, env, is_active),
|
||||
}
|
||||
}
|
||||
|
||||
/// Process VAA message signed by quardians
|
||||
fn handle_submit_vaa<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
data: &[u8],
|
||||
) -> StdResult<HandleResponse> {
|
||||
|
||||
let state = config_read(&deps.storage).load()?;
|
||||
if !state.is_active {
|
||||
return ContractError::ContractInactive.std_err();
|
||||
}
|
||||
|
||||
/* VAA format:
|
||||
|
||||
header (length 6):
|
||||
0 uint8 version (0x01)
|
||||
1 uint32 guardian set index
|
||||
5 uint8 len signatures
|
||||
|
||||
per signature (length 66):
|
||||
0 uint8 index of the signer (in guardian keys)
|
||||
1 [65]uint8 signature
|
||||
|
||||
body:
|
||||
0 uint32 unix seconds
|
||||
4 uint8 action
|
||||
5 [payload_size]uint8 payload */
|
||||
|
||||
const HEADER_LEN: usize = 6;
|
||||
const SIGNATURE_LEN: usize = 66;
|
||||
|
||||
let version = data.get_u8(0);
|
||||
if version != 1 {
|
||||
return ContractError::InvalidVersion.std_err();
|
||||
}
|
||||
|
||||
// Load 4 bytes starting from index 1
|
||||
let vaa_guardian_set_index: u32 = data.get_u32(1);
|
||||
let len_signers = data.get_u8(5) as usize;
|
||||
let body_offset: usize = 6 + SIGNATURE_LEN * len_signers as usize;
|
||||
|
||||
// Hash the body
|
||||
let body = &data[body_offset..];
|
||||
let mut hasher = Keccak256::new();
|
||||
hasher.update(body);
|
||||
let hash = hasher.finalize();
|
||||
|
||||
// Check if VAA with this hash was already accepted
|
||||
if vaa_archive_check(&deps.storage, &hash) {
|
||||
return ContractError::VaaAlreadyExecuted.std_err();
|
||||
}
|
||||
vaa_archive_add(&mut deps.storage, &hash)?;
|
||||
|
||||
// Load and check guardian set
|
||||
let guardian_set = guardian_set_get(&deps.storage, vaa_guardian_set_index);
|
||||
let guardian_set: GuardianSetInfo =
|
||||
guardian_set.or(ContractError::InvalidGuardianSetIndex.std_err())?;
|
||||
|
||||
if guardian_set.expiration_time == 0 || guardian_set.expiration_time > env.block.time {
|
||||
return ContractError::GuardianSetExpired.std_err();
|
||||
}
|
||||
if len_signers < (guardian_set.addresses.len() / 4) * 3 + 1 {
|
||||
return ContractError::NoQuorum.std_err();
|
||||
}
|
||||
|
||||
// Verify guardian signatures
|
||||
let mut last_index: i32 = -1;
|
||||
let mut pos = HEADER_LEN;
|
||||
for _ in 0..len_signers {
|
||||
let index = data.get_u8(pos) as i32;
|
||||
if index <= last_index {
|
||||
return Err(ContractError::WrongGuardianIndexOrder.std());
|
||||
}
|
||||
last_index = index;
|
||||
|
||||
let signature = Signature::try_from(&data[pos + 1..pos + 1 + 64])
|
||||
.or(ContractError::CannotDecodeSignature.std_err())?;
|
||||
let id = RecoverableId::new(data.get_u8(pos + 1 + 64))
|
||||
.or(ContractError::CannotDecodeSignature.std_err())?;
|
||||
let recoverable_signature = RecoverableSignature::new(&signature, id)
|
||||
.or(ContractError::CannotDecodeSignature.std_err())?;
|
||||
|
||||
let verify_key = recoverable_signature
|
||||
.recover_verify_key_from_digest_bytes(&hash)
|
||||
.or(ContractError::CannotRecoverKey.std_err())?;
|
||||
if !keys_equal(&verify_key, &guardian_set.addresses[index as usize]) {
|
||||
return ContractError::GuardianSignatureError.std_err();
|
||||
}
|
||||
pos += SIGNATURE_LEN;
|
||||
}
|
||||
|
||||
// Signatures valid, apply VAA
|
||||
let action = data.get_u8(body_offset + 4);
|
||||
let payload = &data[body_offset + 5..];
|
||||
|
||||
match action {
|
||||
0x01 => {
|
||||
if vaa_guardian_set_index != state.guardian_set_index {
|
||||
return ContractError::NotCurrentGuardianSet.std_err();
|
||||
}
|
||||
vaa_update_guardian_set(deps, env, payload)
|
||||
}
|
||||
0x10 => vaa_transfer(deps, env, payload),
|
||||
_ => ContractError::InvalidVAAAction.std_err(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle wrapped asset registration messages
|
||||
fn handle_register_asset<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
asset_id: &[u8],
|
||||
) -> StdResult<HandleResponse> {
|
||||
let mut bucket = wrapped_asset(&mut deps.storage);
|
||||
let result = bucket.load(asset_id);
|
||||
match result {
|
||||
Ok(_) => {
|
||||
// Asset already registered, return error
|
||||
return ContractError::AssetAlreadyRegistered.std_err();
|
||||
}
|
||||
Err(_) => {
|
||||
bucket.save(asset_id, &env.message.sender)?;
|
||||
|
||||
let contract_address: CanonicalAddr =
|
||||
deps.api.canonical_address(&env.message.sender)?;
|
||||
wrapped_asset_address(&mut deps.storage)
|
||||
.save(contract_address.as_slice(), &asset_id.to_vec())?;
|
||||
|
||||
Ok(HandleResponse {
|
||||
messages: vec![],
|
||||
log: vec![
|
||||
log("action", "register_asset"),
|
||||
log("asset_id", format!("{:?}", asset_id)),
|
||||
log("contract_addr", env.message.sender),
|
||||
],
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn vaa_update_guardian_set<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
data: &[u8],
|
||||
) -> StdResult<HandleResponse> {
|
||||
/* Payload format
|
||||
0 uint32 new_index
|
||||
4 uint8 len(keys)
|
||||
5 [][20]uint8 guardian addresses
|
||||
*/
|
||||
|
||||
let mut state = config_read(&deps.storage).load()?;
|
||||
|
||||
let new_guardian_set_index = data.get_u32(0);
|
||||
|
||||
if new_guardian_set_index != state.guardian_set_index + 1 {
|
||||
return ContractError::GuardianSetIndexIncreaseError.std_err();
|
||||
}
|
||||
let len = data.get_u8(4);
|
||||
|
||||
let mut new_guardian_set = GuardianSetInfo {
|
||||
addresses: vec![],
|
||||
expiration_time: 0,
|
||||
};
|
||||
let mut pos = 5;
|
||||
for _ in 0..len {
|
||||
new_guardian_set.addresses.push(GuardianAddress {
|
||||
bytes: data[pos..pos + 20].to_vec(),
|
||||
});
|
||||
pos += 20;
|
||||
}
|
||||
|
||||
let old_guardian_set_index = state.guardian_set_index;
|
||||
state.guardian_set_index = new_guardian_set_index;
|
||||
|
||||
guardian_set_set(
|
||||
&mut deps.storage,
|
||||
state.guardian_set_index,
|
||||
&new_guardian_set,
|
||||
)?;
|
||||
config(&mut deps.storage).save(&state)?;
|
||||
|
||||
let mut old_guardian_set = guardian_set_get(&deps.storage, old_guardian_set_index)?;
|
||||
old_guardian_set.expiration_time = env.block.time + state.guardian_set_expirity;
|
||||
guardian_set_set(&mut deps.storage, old_guardian_set_index, &old_guardian_set)?;
|
||||
|
||||
// TODO: Apply new guardian set
|
||||
Ok(HandleResponse {
|
||||
messages: vec![],
|
||||
log: vec![
|
||||
log("action", "guardian_set_change"),
|
||||
log("old", old_guardian_set_index),
|
||||
log("new", state.guardian_set_index),
|
||||
],
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn vaa_transfer<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
data: &[u8],
|
||||
) -> StdResult<HandleResponse> {
|
||||
/* Payload format:
|
||||
0 uint32 nonce
|
||||
4 uint8 source_chain
|
||||
5 uint8 target_chain
|
||||
6 [32]uint8 source_address
|
||||
38 [32]uint8 target_address
|
||||
70 uint8 token_chain
|
||||
71 [32]uint8 token_address
|
||||
103 uint8 decimals
|
||||
104 uint256 amount */
|
||||
|
||||
let source_chain = data.get_u8(4);
|
||||
let target_chain = data.get_u8(5);
|
||||
|
||||
let target_address = data.get_address(38);
|
||||
|
||||
let token_chain = data.get_u8(70);
|
||||
let (not_supported_amount, amount) = data.get_u256(104);
|
||||
|
||||
// Check high 128 bit of amount value to be empty
|
||||
if not_supported_amount != 0 {
|
||||
return ContractError::AmountTooHigh.std_err();
|
||||
}
|
||||
|
||||
// Check if source and target chains are different
|
||||
if source_chain == target_chain {
|
||||
return ContractError::SameSourceAndTarget.std_err();
|
||||
}
|
||||
|
||||
// Check if transfer is incoming
|
||||
if target_chain != CHAIN_ID {
|
||||
return ContractError::WrongTargetChain.std_err();
|
||||
}
|
||||
|
||||
if token_chain != CHAIN_ID {
|
||||
let mut asset_id: Vec<u8> = vec![];
|
||||
asset_id.push(token_chain);
|
||||
let asset_address = data.get_bytes32(71);
|
||||
asset_id.extend_from_slice(asset_address);
|
||||
|
||||
let mut hasher = Keccak256::new();
|
||||
hasher.update(asset_id);
|
||||
let asset_id = hasher.finalize();
|
||||
|
||||
let mut messages: Vec<CosmosMsg> = vec![];
|
||||
|
||||
// Check if this asset is already deployed
|
||||
match wrapped_asset_read(&deps.storage).load(&asset_id) {
|
||||
Ok(contract_addr) => {
|
||||
// Asset already deployed, just mint
|
||||
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
|
||||
contract_addr,
|
||||
msg: to_binary(&WrappedMsg::Mint {
|
||||
recipient: deps.api.human_address(&target_address)?,
|
||||
amount: Uint128::from(amount),
|
||||
})?,
|
||||
send: vec![],
|
||||
}));
|
||||
}
|
||||
Err(_) => {
|
||||
// Asset is not deployed yet, deploy and mint
|
||||
let state = config_read(&deps.storage).load()?;
|
||||
messages.push(CosmosMsg::Wasm(WasmMsg::Instantiate {
|
||||
code_id: state.wrapped_asset_code_id,
|
||||
msg: to_binary(&WrappedInit {
|
||||
asset_chain: token_chain,
|
||||
asset_address: asset_address.to_vec(),
|
||||
decimals: data.get_u8(103),
|
||||
mint: Some(InitMint {
|
||||
recipient: deps.api.human_address(&target_address)?,
|
||||
amount: Uint128::from(amount),
|
||||
}),
|
||||
init_hook: Some(InitHook {
|
||||
contract_addr: env.contract.address,
|
||||
msg: to_binary(&HandleMsg::RegisterAssetHook {
|
||||
asset_id: asset_id.to_vec(),
|
||||
})?,
|
||||
}),
|
||||
})?,
|
||||
send: vec![],
|
||||
label: None,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(HandleResponse {
|
||||
messages,
|
||||
log: vec![],
|
||||
data: None,
|
||||
})
|
||||
} else {
|
||||
let token_address = data.get_address(71);
|
||||
|
||||
Ok(HandleResponse {
|
||||
messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
|
||||
contract_addr: deps.api.human_address(&token_address)?,
|
||||
msg: to_binary(&TokenMsg::Transfer {
|
||||
recipient: deps.api.human_address(&target_address)?,
|
||||
amount: Uint128::from(amount),
|
||||
})?,
|
||||
send: vec![],
|
||||
})],
|
||||
log: vec![], // TODO: Add log entries
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_lock_assets<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
asset: HumanAddr,
|
||||
amount: Uint128,
|
||||
recipient: Vec<u8>,
|
||||
target_chain: u8,
|
||||
nonce: u32,
|
||||
) -> StdResult<HandleResponse> {
|
||||
if target_chain == CHAIN_ID {
|
||||
return ContractError::SameSourceAndTarget.std_err();
|
||||
}
|
||||
|
||||
if amount.is_zero() {
|
||||
return ContractError::AmountTooLow.std_err();
|
||||
}
|
||||
|
||||
let state = config_read(&deps.storage).load()?;
|
||||
if !state.is_active {
|
||||
return ContractError::ContractInactive.std_err();
|
||||
}
|
||||
|
||||
let asset_chain: u8;
|
||||
let asset_address: Vec<u8>;
|
||||
|
||||
// Query asset details
|
||||
let request = QueryRequest::<()>::Wasm(WasmQuery::Smart {
|
||||
contract_addr: asset.clone(),
|
||||
msg: to_binary(&TokenQuery::TokenInfo {})?,
|
||||
});
|
||||
let token_info: TokenInfoResponse = deps.querier.custom_query(&request)?;
|
||||
|
||||
let decimals: u8 = token_info.decimals;
|
||||
|
||||
let asset_canonical: CanonicalAddr = deps.api.canonical_address(&asset)?;
|
||||
|
||||
let mut messages: Vec<CosmosMsg> = vec![];
|
||||
|
||||
match wrapped_asset_address_read(&deps.storage).load(asset_canonical.as_slice()) {
|
||||
Ok(_) => {
|
||||
// This is a deployed wrapped asset, burn it
|
||||
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
|
||||
contract_addr: asset.clone(),
|
||||
msg: to_binary(&WrappedMsg::Burn {
|
||||
account: env.message.sender.clone(),
|
||||
amount: Uint128::from(amount),
|
||||
})?,
|
||||
send: vec![],
|
||||
}));
|
||||
let request = QueryRequest::<()>::Wasm(WasmQuery::Smart {
|
||||
contract_addr: asset,
|
||||
msg: to_binary(&WrappedQuery::WrappedAssetInfo {})?,
|
||||
});
|
||||
let wrapped_token_info: WrappedAssetInfoResponse =
|
||||
deps.querier.custom_query(&request)?;
|
||||
asset_chain = wrapped_token_info.asset_chain;
|
||||
asset_address = wrapped_token_info.asset_address;
|
||||
}
|
||||
Err(_) => {
|
||||
// This is a regular asset, transfer its balance
|
||||
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
|
||||
contract_addr: asset.clone(),
|
||||
msg: to_binary(&TokenMsg::TransferFrom {
|
||||
owner: env.message.sender.clone(),
|
||||
recipient: env.contract.address.clone(),
|
||||
amount: Uint128::from(amount),
|
||||
})?,
|
||||
send: vec![],
|
||||
}));
|
||||
asset_address = extend_address_to_32(&asset_canonical);
|
||||
asset_chain = CHAIN_ID;
|
||||
}
|
||||
};
|
||||
|
||||
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
|
||||
contract_addr: env.contract.address,
|
||||
msg: to_binary(&HandleMsg::TokensLocked {
|
||||
target_chain,
|
||||
token_chain: asset_chain,
|
||||
token_decimals: decimals,
|
||||
token: asset_address,
|
||||
sender: extend_address_to_32(&deps.api.canonical_address(&env.message.sender)?),
|
||||
recipient,
|
||||
amount,
|
||||
nonce,
|
||||
})?,
|
||||
send: vec![],
|
||||
}));
|
||||
|
||||
Ok(HandleResponse {
|
||||
messages,
|
||||
log: vec![],
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn handle_tokens_locked(
|
||||
target_chain: u8,
|
||||
token_chain: u8,
|
||||
token_decimals: u8,
|
||||
token: Vec<u8>,
|
||||
sender: Vec<u8>,
|
||||
recipient: Vec<u8>,
|
||||
amount: Uint128,
|
||||
nonce: u32,
|
||||
) -> StdResult<HandleResponse> {
|
||||
// Dummy handler to record token lock as transaction
|
||||
Ok(HandleResponse {
|
||||
messages: vec![],
|
||||
log: vec![
|
||||
log("locked.target_chain", target_chain),
|
||||
log("locked.token_chain", token_chain),
|
||||
log("locked.token_decimals", token_decimals),
|
||||
log("locked.token", hex::encode(token)),
|
||||
log("locked.sender", hex::encode(sender)),
|
||||
log("locked.recipient", hex::encode(recipient)),
|
||||
log("locked.amount", amount),
|
||||
log("locked.nonce", nonce),
|
||||
],
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn handle_set_active<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
env: Env,
|
||||
is_active: bool,
|
||||
) -> StdResult<HandleResponse> {
|
||||
let mut state = config_read(&deps.storage).load()?;
|
||||
|
||||
if deps.api.canonical_address(&env.message.sender)? != state.owner {
|
||||
return ContractError::PermissionDenied.std_err();
|
||||
}
|
||||
|
||||
state.is_active = is_active;
|
||||
|
||||
config(&mut deps.storage).save(&state)?;
|
||||
|
||||
Ok(HandleResponse {
|
||||
messages: vec![],
|
||||
log: vec![],
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn query<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &Extern<S, A, Q>,
|
||||
msg: QueryMsg,
|
||||
) -> StdResult<Binary> {
|
||||
match msg {
|
||||
QueryMsg::GuardianSetInfo {} => to_binary(&query_query_guardian_set_info(deps)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query_query_guardian_set_info<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &Extern<S, A, Q>,
|
||||
) -> StdResult<GuardianSetInfoResponse> {
|
||||
let state = config_read(&deps.storage).load()?;
|
||||
let guardian_set = guardian_set_get(&deps.storage, state.guardian_set_index)?;
|
||||
let res = GuardianSetInfoResponse {
|
||||
guardian_set_index: state.guardian_set_index,
|
||||
addresses: guardian_set.addresses,
|
||||
};
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn keys_equal(a: &VerifyKey, b: &GuardianAddress) -> bool {
|
||||
let mut hasher = Keccak256::new();
|
||||
|
||||
let point: EncodedPoint = EncodedPoint::from(a);
|
||||
let point = point.decompress();
|
||||
if bool::from(point.is_none()) {
|
||||
return false;
|
||||
}
|
||||
let point = point.unwrap();
|
||||
|
||||
hasher.update(&point.as_bytes()[1..]);
|
||||
let a = &hasher.finalize()[12..];
|
||||
|
||||
let b = &b.bytes;
|
||||
if a.len() != b.len() {
|
||||
return false;
|
||||
}
|
||||
for (ai, bi) in a.iter().zip(b.iter()) {
|
||||
if ai != bi {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::state::GuardianSetInfo;
|
||||
use cosmwasm_std::testing::{mock_dependencies, mock_env};
|
||||
use cosmwasm_std::HumanAddr;
|
||||
|
||||
const ADDR_1: &str = "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe";
|
||||
const ADDR_2: &str = "8575Df9b3c97B4E267Deb92d93137844A97A0132";
|
||||
|
||||
const VAA_VALID_TRANSFER: &str = "010000000001005468beb21caff68710b2af2d60a986245bf85099509b6babe990a6c32456b44b3e2e9493e3056b7d5892957e14beab24be02dab77ed6c8915000e4a1267f78f400000007d01000000038018002010400000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000";
|
||||
const VAA_VALID_GUARDIAN_SET_CHANGE: &str = "01000000000100d90d6f9cbc0458599cbe4d267bc9221b54955b94cb5cb338aeb845bdc9dd275f558871ea479de9cc0b44cfb2a07344431a3adbd2f98aa86f4e12ff4aba061b7f00000007d00100000001018575df9b3c97b4e267deb92d93137844a97a0132";
|
||||
|
||||
const CANONICAL_LENGTH: usize = 20;
|
||||
|
||||
fn do_init_default_guardians<S: Storage, A: Api, Q: Querier>(deps: &mut Extern<S, A, Q>) {
|
||||
do_init(deps, &vec![GuardianAddress::from(ADDR_1)]);
|
||||
}
|
||||
|
||||
fn do_init<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
guardians: &Vec<GuardianAddress>,
|
||||
) {
|
||||
let init_msg = InitMsg {
|
||||
initial_guardian_set: GuardianSetInfo {
|
||||
addresses: guardians.clone(),
|
||||
expiration_time: 100,
|
||||
},
|
||||
guardian_set_expirity: 50,
|
||||
wrapped_asset_code_id: 999,
|
||||
};
|
||||
let env = mock_env(&HumanAddr::from("creator"), &[]);
|
||||
let res = init(deps, env, init_msg).unwrap();
|
||||
assert_eq!(0, res.messages.len());
|
||||
|
||||
// TODO: Query and check contract state and guardians storage
|
||||
}
|
||||
|
||||
fn submit_vaa<S: Storage, A: Api, Q: Querier>(
|
||||
deps: &mut Extern<S, A, Q>,
|
||||
vaa: &str,
|
||||
) -> StdResult<HandleResponse> {
|
||||
let msg = HandleMsg::SubmitVAA {
|
||||
vaa: hex::decode(vaa).expect("Decoding failed"),
|
||||
};
|
||||
let env = mock_env(&HumanAddr::from("creator"), &[]);
|
||||
|
||||
handle(deps, env, msg)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_init() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
do_init_default_guardians(&mut deps);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_vaa_token_transfer() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
do_init_default_guardians(&mut deps);
|
||||
|
||||
let messages = submit_vaa(&mut deps, VAA_VALID_TRANSFER).unwrap().messages;
|
||||
assert_eq!(1, messages.len());
|
||||
let msg = &messages[0];
|
||||
match msg {
|
||||
CosmosMsg::Wasm(wasm_msg) => match wasm_msg {
|
||||
WasmMsg::Instantiate {
|
||||
code_id,
|
||||
msg: _,
|
||||
send,
|
||||
label,
|
||||
} => {
|
||||
assert_eq!(*code_id, 999);
|
||||
assert_eq!(*label, None);
|
||||
assert_eq!(*send, vec![]);
|
||||
}
|
||||
_ => panic!("Wrong message type"),
|
||||
},
|
||||
_ => panic!("Wrong message type"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn same_vaa_twice_error() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
do_init_default_guardians(&mut deps);
|
||||
|
||||
let _ = submit_vaa(&mut deps, VAA_VALID_TRANSFER).unwrap();
|
||||
let e = submit_vaa(&mut deps, VAA_VALID_TRANSFER).unwrap_err();
|
||||
assert_eq!(e, ContractError::VaaAlreadyExecuted.std());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_vaa_guardian_set_change() {
|
||||
let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]);
|
||||
do_init_default_guardians(&mut deps);
|
||||
|
||||
let messages = submit_vaa(&mut deps, VAA_VALID_GUARDIAN_SET_CHANGE)
|
||||
.unwrap()
|
||||
.messages;
|
||||
assert_eq!(0, messages.len());
|
||||
|
||||
// Check storage
|
||||
let state = config_read(&deps.storage)
|
||||
.load()
|
||||
.expect("Cannot load config storage");
|
||||
assert_eq!(state.guardian_set_index, 1);
|
||||
let guardian_set_info = guardian_set_get(&deps.storage, state.guardian_set_index)
|
||||
.expect("Cannot find guardian set");
|
||||
assert_eq!(
|
||||
guardian_set_info,
|
||||
GuardianSetInfo {
|
||||
addresses: vec![GuardianAddress::from(ADDR_2)],
|
||||
expiration_time: 0
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
use cosmwasm_std::StdError;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ContractError {
|
||||
/// Invalid VAA version
|
||||
#[error("InvalidVersion")]
|
||||
InvalidVersion,
|
||||
|
||||
/// Guardian set with this index does not exist
|
||||
#[error("InvalidGuardianSetIndex")]
|
||||
InvalidGuardianSetIndex,
|
||||
|
||||
/// Guardian set expiration date is zero or in the past
|
||||
#[error("GuardianSetExpired")]
|
||||
GuardianSetExpired,
|
||||
|
||||
/// Not enough signers on the VAA
|
||||
#[error("NoQuorum")]
|
||||
NoQuorum,
|
||||
|
||||
/// Wrong guardian index order, order must be ascending
|
||||
#[error("WrongGuardianIndexOrder")]
|
||||
WrongGuardianIndexOrder,
|
||||
|
||||
/// Some problem with signature decoding from bytes
|
||||
#[error("CannotDecodeSignature")]
|
||||
CannotDecodeSignature,
|
||||
|
||||
/// Some problem with public key recovery from the signature
|
||||
#[error("CannotRecoverKey")]
|
||||
CannotRecoverKey,
|
||||
|
||||
/// Recovered pubkey from signature does not match guardian address
|
||||
#[error("GuardianSignatureError")]
|
||||
GuardianSignatureError,
|
||||
|
||||
/// VAA action code not recognized
|
||||
#[error("InvalidVAAAction")]
|
||||
InvalidVAAAction,
|
||||
|
||||
/// VAA guardian set is not current
|
||||
#[error("NotCurrentGuardianSet")]
|
||||
NotCurrentGuardianSet,
|
||||
|
||||
/// Only 128-bit amounts are supported
|
||||
#[error("AmountTooHigh")]
|
||||
AmountTooHigh,
|
||||
|
||||
/// Amount should be higher than zero
|
||||
#[error("AmountTooLow")]
|
||||
AmountTooLow,
|
||||
|
||||
/// Source and target chain ids must be different
|
||||
#[error("SameSourceAndTarget")]
|
||||
SameSourceAndTarget,
|
||||
|
||||
/// Target chain id must be the same as the current CHAIN_ID
|
||||
#[error("WrongTargetChain")]
|
||||
WrongTargetChain,
|
||||
|
||||
/// Wrapped asset init hook sent twice for the same asset id
|
||||
#[error("AssetAlreadyRegistered")]
|
||||
AssetAlreadyRegistered,
|
||||
|
||||
/// Guardian set must increase in steps of 1
|
||||
#[error("GuardianSetIndexIncreaseError")]
|
||||
GuardianSetIndexIncreaseError,
|
||||
|
||||
/// VAA was already executed
|
||||
#[error("VaaAlreadyExecuted")]
|
||||
VaaAlreadyExecuted,
|
||||
|
||||
/// Message sender not permitted to execute this operation
|
||||
#[error("PermissionDenied")]
|
||||
PermissionDenied,
|
||||
|
||||
/// Attempt to execute contract action while it is inactive
|
||||
#[error("ContractInactive")]
|
||||
ContractInactive,
|
||||
}
|
||||
|
||||
impl ContractError {
|
||||
pub fn std(&self) -> StdError {
|
||||
StdError::GenericErr {
|
||||
msg: format!("{}", self),
|
||||
backtrace: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn std_err<T>(&self) -> Result<T, StdError> {
|
||||
Err(self.std())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
mod byte_utils;
|
||||
pub mod contract;
|
||||
mod error;
|
||||
pub mod msg;
|
||||
pub mod state;
|
||||
|
||||
pub use crate::error::ContractError;
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", not(feature = "library")))]
|
||||
cosmwasm_std::create_entry_points!(contract);
|
|
@ -0,0 +1,55 @@
|
|||
use cosmwasm_std::{HumanAddr, Uint128};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::state::{GuardianAddress, GuardianSetInfo};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct InitMsg {
|
||||
pub initial_guardian_set: GuardianSetInfo,
|
||||
pub guardian_set_expirity: u64,
|
||||
pub wrapped_asset_code_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HandleMsg {
|
||||
SubmitVAA {
|
||||
vaa: Vec<u8>,
|
||||
},
|
||||
RegisterAssetHook {
|
||||
asset_id: Vec<u8>,
|
||||
},
|
||||
LockAssets {
|
||||
asset: HumanAddr,
|
||||
amount: Uint128,
|
||||
recipient: Vec<u8>,
|
||||
target_chain: u8,
|
||||
nonce: u32,
|
||||
},
|
||||
TokensLocked {
|
||||
target_chain: u8,
|
||||
token_chain: u8,
|
||||
token_decimals: u8,
|
||||
token: Vec<u8>,
|
||||
sender: Vec<u8>,
|
||||
recipient: Vec<u8>,
|
||||
amount: Uint128,
|
||||
nonce: u32,
|
||||
},
|
||||
SetActive {
|
||||
is_active: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum QueryMsg {
|
||||
GuardianSetInfo {},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct GuardianSetInfoResponse {
|
||||
pub guardian_set_index: u32, // Current guardian set index
|
||||
pub addresses: Vec<GuardianAddress>, // List of querdian addresses
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cosmwasm_std::{CanonicalAddr, HumanAddr, StdResult, Storage};
|
||||
use cosmwasm_storage::{
|
||||
bucket, bucket_read, singleton, singleton_read, Bucket, ReadonlyBucket, ReadonlySingleton,
|
||||
Singleton,
|
||||
};
|
||||
|
||||
pub static CONFIG_KEY: &[u8] = b"config";
|
||||
pub static GUARDIAN_SET_KEY: &[u8] = b"guardian_set";
|
||||
pub static WRAPPED_ASSET_KEY: &[u8] = b"wrapped_asset";
|
||||
pub static WRAPPED_ASSET_ADDRESS_KEY: &[u8] = b"wrapped_asset_address";
|
||||
|
||||
// Guardian set information
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct ConfigInfo {
|
||||
// Current active guardian set
|
||||
pub guardian_set_index: u32,
|
||||
|
||||
// Period for which a guardian set stays active after it has been replaced
|
||||
pub guardian_set_expirity: u64,
|
||||
|
||||
// Code id for wrapped asset contract
|
||||
pub wrapped_asset_code_id: u64,
|
||||
|
||||
// Contract owner address, it can make contract active/inactive
|
||||
pub owner: CanonicalAddr,
|
||||
|
||||
// If true the contract is active and functioning
|
||||
pub is_active: bool,
|
||||
}
|
||||
|
||||
// Guardian address
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct GuardianAddress {
|
||||
pub bytes: Vec<u8>, // 20-byte addresses
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
use hex;
|
||||
#[cfg(test)]
|
||||
impl GuardianAddress {
|
||||
pub fn from(string: &str) -> GuardianAddress {
|
||||
GuardianAddress {
|
||||
bytes: hex::decode(string).expect("Decoding failed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guardian set information
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct GuardianSetInfo {
|
||||
pub addresses: Vec<GuardianAddress>, // List of guardian addresses
|
||||
pub expiration_time: u64, // Guardian set expiration time
|
||||
}
|
||||
|
||||
// Wormhole contract generic information
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct WormholeInfo {
|
||||
// Period for which a guardian set stays active after it has been replaced
|
||||
pub guardian_set_expirity: u64,
|
||||
}
|
||||
|
||||
pub fn config<S: Storage>(storage: &mut S) -> Singleton<S, ConfigInfo> {
|
||||
singleton(storage, CONFIG_KEY)
|
||||
}
|
||||
|
||||
pub fn config_read<S: Storage>(storage: &S) -> ReadonlySingleton<S, ConfigInfo> {
|
||||
singleton_read(storage, CONFIG_KEY)
|
||||
}
|
||||
|
||||
pub fn guardian_set_set<S: Storage>(
|
||||
storage: &mut S,
|
||||
index: u32,
|
||||
data: &GuardianSetInfo,
|
||||
) -> StdResult<()> {
|
||||
bucket(GUARDIAN_SET_KEY, storage).save(&index.to_le_bytes(), data)
|
||||
}
|
||||
|
||||
pub fn guardian_set_get<S: Storage>(storage: &S, index: u32) -> StdResult<GuardianSetInfo> {
|
||||
bucket_read(GUARDIAN_SET_KEY, storage).load(&index.to_le_bytes())
|
||||
}
|
||||
|
||||
pub fn vaa_archive_add<S: Storage>(storage: &mut S, hash: &[u8]) -> StdResult<()> {
|
||||
bucket(GUARDIAN_SET_KEY, storage).save(hash, &true)
|
||||
}
|
||||
|
||||
pub fn vaa_archive_check<S: Storage>(storage: &S, hash: &[u8]) -> bool {
|
||||
bucket_read(GUARDIAN_SET_KEY, storage)
|
||||
.load(&hash)
|
||||
.or::<bool>(Ok(false))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn wrapped_asset<S: Storage>(storage: &mut S) -> Bucket<S, HumanAddr> {
|
||||
bucket(WRAPPED_ASSET_KEY, storage)
|
||||
}
|
||||
|
||||
pub fn wrapped_asset_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, HumanAddr> {
|
||||
bucket_read(WRAPPED_ASSET_KEY, storage)
|
||||
}
|
||||
|
||||
pub fn wrapped_asset_address<S: Storage>(storage: &mut S) -> Bucket<S, Vec<u8>> {
|
||||
bucket(WRAPPED_ASSET_ADDRESS_KEY, storage)
|
||||
}
|
||||
|
||||
pub fn wrapped_asset_address_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, Vec<u8>> {
|
||||
bucket_read(WRAPPED_ASSET_ADDRESS_KEY, storage)
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
static WASM: &[u8] = include_bytes!("../../../target/wasm32-unknown-unknown/release/wormhole.wasm");
|
||||
|
||||
use cosmwasm_std::{from_slice, Env, HumanAddr, InitResponse};
|
||||
use cosmwasm_storage::to_length_prefixed;
|
||||
use cosmwasm_vm::testing::{init, mock_env, mock_instance, MockApi, MockQuerier, MockStorage};
|
||||
use cosmwasm_vm::{Instance, Storage, Api};
|
||||
|
||||
use wormhole::msg::InitMsg;
|
||||
use wormhole::state::{ConfigInfo, GuardianAddress, GuardianSetInfo, CONFIG_KEY};
|
||||
|
||||
use hex;
|
||||
|
||||
enum TestAddress {
|
||||
INITIALIZER,
|
||||
}
|
||||
|
||||
impl TestAddress {
|
||||
fn value(&self) -> HumanAddr {
|
||||
match self {
|
||||
TestAddress::INITIALIZER => HumanAddr::from("initializer"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mock_env_height(signer: &HumanAddr, height: u64, time: u64) -> Env {
|
||||
let mut env = mock_env(signer, &[]);
|
||||
env.block.height = height;
|
||||
env.block.time = time;
|
||||
env
|
||||
}
|
||||
|
||||
fn get_config_info<S: Storage>(storage: &S) -> ConfigInfo {
|
||||
let key = to_length_prefixed(CONFIG_KEY);
|
||||
let data = storage
|
||||
.get(&key)
|
||||
.0
|
||||
.expect("error getting data")
|
||||
.expect("data should exist");
|
||||
from_slice(&data).expect("invalid data")
|
||||
}
|
||||
|
||||
fn do_init(
|
||||
height: u64,
|
||||
guardians: &Vec<GuardianAddress>,
|
||||
) -> Instance<MockStorage, MockApi, MockQuerier> {
|
||||
let mut deps = mock_instance(WASM, &[]);
|
||||
let init_msg = InitMsg {
|
||||
initial_guardian_set: GuardianSetInfo {
|
||||
addresses: guardians.clone(),
|
||||
expiration_time: 100,
|
||||
},
|
||||
guardian_set_expirity: 50,
|
||||
wrapped_asset_code_id: 999,
|
||||
};
|
||||
let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0);
|
||||
let owner = deps.api.canonical_address(&TestAddress::INITIALIZER.value()).0.unwrap();
|
||||
let res: InitResponse = init(&mut deps, env, init_msg).unwrap();
|
||||
assert_eq!(0, res.messages.len());
|
||||
|
||||
// query the store directly
|
||||
deps.with_storage(|storage| {
|
||||
assert_eq!(
|
||||
get_config_info(storage),
|
||||
ConfigInfo {
|
||||
guardian_set_index: 0,
|
||||
guardian_set_expirity: 50,
|
||||
wrapped_asset_code_id: 999,
|
||||
owner,
|
||||
is_active: true,
|
||||
}
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
deps
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_works() {
|
||||
let guardians = vec![GuardianAddress::from(GuardianAddress {
|
||||
bytes: hex::decode("beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe").expect("Decoding failed"),
|
||||
})];
|
||||
let _deps = do_init(111, &guardians);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
# Wormhole + Terra local test environment
|
||||
|
||||
For the list of dependencies please follow [DEVELOP.md](../../DEVELOP.md)
|
||||
|
||||
Additional dependencies:
|
||||
- [Node.js](https://nodejs.org/) >= 14.x, [ts-node](https://www.npmjs.com/package/ts-node) >= 8.x
|
||||
|
||||
Start Tilt from the project root:
|
||||
|
||||
tilt up
|
||||
|
||||
Afterwards use test scripts in `terra/tools` folder:
|
||||
|
||||
npm install
|
||||
npm run prepare-token
|
||||
npm run prepare-wormhole
|
||||
|
||||
These commands will give you two important addresses: test token address and Wormhole contract address on Terra. Now you need to change guardian configuration to monitor the right contract. Copy Wormhole contract address and replace existing address in file `devnet/bridge-terra.yaml` (line 67). Save the changes and monitor Tilt dashboard until guardian services restart.
|
||||
|
||||
Now use both token address and Wormhole contract address to issue tocken lock transaction:
|
||||
|
||||
npm run lock-tocken -- TOKEN_CONTRACT WORMHOLE_CONTRACT 1000
|
||||
|
||||
Where 1000 is a sample amount to transfer. After this command is issued monitor Guardian service in Tilt dashboard to see its effects propagated to the destination blockchain (in this case it is Ethereum).
|
|
@ -0,0 +1,25 @@
|
|||
import { execute_contract, query_contract } from './utils';
|
||||
|
||||
async function script() {
|
||||
if (process.argv.length < 5) {
|
||||
console.log('Required 3 params TOKEN_CONTRACT, WORMHOLE_CONTRACT, integer AMOUNT');
|
||||
}
|
||||
let token_contract = process.argv[2];
|
||||
let wormhole_contract = process.argv[3];
|
||||
let amount = process.argv[4];
|
||||
|
||||
let allowanceResult = await execute_contract(token_contract, {increase_allowance: {spender: wormhole_contract, amount}});
|
||||
if (allowanceResult == null) return;
|
||||
console.log('Allowance increased');
|
||||
let lockResult = await execute_contract(wormhole_contract, {lock_assets: {
|
||||
asset: token_contract,
|
||||
amount,
|
||||
recipient: [...Buffer.from('00000000000000000000000019a4437E2BA06bF1FA42C56Fb269Ca0d30f60716', 'hex')],
|
||||
target_chain: 2, // Ethereum
|
||||
nonce: Date.now() % 1000000
|
||||
}});
|
||||
if (lockResult == null) return;
|
||||
console.log('Tokens locked');
|
||||
}
|
||||
|
||||
script();
|
|
@ -0,0 +1,438 @@
|
|||
{
|
||||
"name": "terra-contract-tools",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@terra-money/terra.js": {
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-0.5.12.tgz",
|
||||
"integrity": "sha512-3UZWMT3Tu+MOQrHZ8uEtHL+hurKbe1QVm8x+qWOe4+IOeY3eWdVeBIkHflhGI8NU31v/r5eznbTuy7kEMA4CMQ==",
|
||||
"requires": {
|
||||
"axios": "^0.20.0",
|
||||
"bech32": "^1.1.4",
|
||||
"bip32": "^2.0.6",
|
||||
"bip39": "^3.0.2",
|
||||
"bufferutil": "^4.0.1",
|
||||
"crypto-js": "3.3.0",
|
||||
"decimal.js": "^10.2.1",
|
||||
"post-message-stream": "^3.0.0",
|
||||
"secp256k1": "^4.0.2",
|
||||
"utf-8-validate": "^5.0.2",
|
||||
"ws": "^7.3.1"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.14.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz",
|
||||
"integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.20.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
|
||||
"integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"base-x": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz",
|
||||
"integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"bech32": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
|
||||
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ=="
|
||||
},
|
||||
"bindings": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||
"requires": {
|
||||
"file-uri-to-path": "1.0.0"
|
||||
}
|
||||
},
|
||||
"bip32": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz",
|
||||
"integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==",
|
||||
"requires": {
|
||||
"@types/node": "10.12.18",
|
||||
"bs58check": "^2.1.1",
|
||||
"create-hash": "^1.2.0",
|
||||
"create-hmac": "^1.1.7",
|
||||
"tiny-secp256k1": "^1.1.3",
|
||||
"typeforce": "^1.11.5",
|
||||
"wif": "^2.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "10.12.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
|
||||
"integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"bip39": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz",
|
||||
"integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==",
|
||||
"requires": {
|
||||
"@types/node": "11.11.6",
|
||||
"create-hash": "^1.1.0",
|
||||
"pbkdf2": "^3.0.9",
|
||||
"randombytes": "^2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "11.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz",
|
||||
"integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"bn.js": {
|
||||
"version": "4.11.9",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
|
||||
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw=="
|
||||
},
|
||||
"brorand": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
|
||||
},
|
||||
"bs58": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
|
||||
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
|
||||
"requires": {
|
||||
"base-x": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"bs58check": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
|
||||
"integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
|
||||
"requires": {
|
||||
"bs58": "^4.0.0",
|
||||
"create-hash": "^1.1.0",
|
||||
"safe-buffer": "^5.1.2"
|
||||
}
|
||||
},
|
||||
"bufferutil": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.2.tgz",
|
||||
"integrity": "sha512-AtnG3W6M8B2n4xDQ5R+70EXvOpnXsFYg/AK2yTZd+HQ/oxAdz+GI+DvjmhBw3L0ole+LJ0ngqY4JMbDzkfNzhA==",
|
||||
"requires": {
|
||||
"node-gyp-build": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"cipher-base": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
||||
"integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"create-hash": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
|
||||
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
|
||||
"requires": {
|
||||
"cipher-base": "^1.0.1",
|
||||
"inherits": "^2.0.1",
|
||||
"md5.js": "^1.3.4",
|
||||
"ripemd160": "^2.0.1",
|
||||
"sha.js": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"create-hmac": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
|
||||
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
|
||||
"requires": {
|
||||
"cipher-base": "^1.0.3",
|
||||
"create-hash": "^1.1.0",
|
||||
"inherits": "^2.0.1",
|
||||
"ripemd160": "^2.0.0",
|
||||
"safe-buffer": "^5.0.1",
|
||||
"sha.js": "^2.4.8"
|
||||
}
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
|
||||
"integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q=="
|
||||
},
|
||||
"decimal.js": {
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
|
||||
"integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw=="
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
|
||||
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
|
||||
"requires": {
|
||||
"bn.js": "^4.4.0",
|
||||
"brorand": "^1.0.1",
|
||||
"hash.js": "^1.0.0",
|
||||
"hmac-drbg": "^1.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"minimalistic-assert": "^1.0.0",
|
||||
"minimalistic-crypto-utils": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
|
||||
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
|
||||
},
|
||||
"hash-base": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
|
||||
"integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.6.0",
|
||||
"safe-buffer": "^5.2.0"
|
||||
}
|
||||
},
|
||||
"hash.js": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
|
||||
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"minimalistic-assert": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
||||
"integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
|
||||
"requires": {
|
||||
"hash.js": "^1.0.3",
|
||||
"minimalistic-assert": "^1.0.0",
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"md5.js": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
||||
"integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
|
||||
"requires": {
|
||||
"hash-base": "^3.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"safe-buffer": "^5.1.2"
|
||||
}
|
||||
},
|
||||
"minimalistic-assert": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
|
||||
},
|
||||
"minimalistic-crypto-utils": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
||||
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.2",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
|
||||
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
|
||||
"integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
|
||||
},
|
||||
"node-gyp-build": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
|
||||
"integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg=="
|
||||
},
|
||||
"pbkdf2": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
|
||||
"integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
|
||||
"requires": {
|
||||
"create-hash": "^1.1.2",
|
||||
"create-hmac": "^1.1.4",
|
||||
"ripemd160": "^2.0.1",
|
||||
"safe-buffer": "^5.0.1",
|
||||
"sha.js": "^2.4.8"
|
||||
}
|
||||
},
|
||||
"post-message-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=",
|
||||
"requires": {
|
||||
"readable-stream": "^2.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"ripemd160": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
|
||||
"integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
|
||||
"requires": {
|
||||
"hash-base": "^3.0.0",
|
||||
"inherits": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
},
|
||||
"secp256k1": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
|
||||
"integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
|
||||
"requires": {
|
||||
"elliptic": "^6.5.2",
|
||||
"node-addon-api": "^2.0.0",
|
||||
"node-gyp-build": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"sha.js": {
|
||||
"version": "2.4.11",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
|
||||
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"tiny-secp256k1": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.5.tgz",
|
||||
"integrity": "sha512-duE2hSLSQIpHGzmK48OgRrGTi+4OTkXLC6aa86uOYQ6LLCYZSarVKIAvEtY7MoXjoL6bOXMSerEGMzrvW4SkDw==",
|
||||
"requires": {
|
||||
"bindings": "^1.3.0",
|
||||
"bn.js": "^4.11.8",
|
||||
"create-hmac": "^1.1.7",
|
||||
"elliptic": "^6.4.0",
|
||||
"nan": "^2.13.2"
|
||||
}
|
||||
},
|
||||
"typeforce": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
|
||||
"integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g=="
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.3.tgz",
|
||||
"integrity": "sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A==",
|
||||
"requires": {
|
||||
"node-gyp-build": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"wif": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz",
|
||||
"integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=",
|
||||
"requires": {
|
||||
"bs58check": "<3.0.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
|
||||
"integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "terra-contract-tools",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build-contracts": "( cd .. && docker run --rm -v \"$(pwd)\":/code --mount type=volume,source=\"$(basename \"$(pwd)\")_cache\",target=/code/target --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry cosmwasm/workspace-optimizer:0.10.4 )",
|
||||
"prepare-token": "ts-node prepare-token.ts",
|
||||
"prepare-wormhole": "ts-node prepare-wormhole.ts",
|
||||
"lock-token": "ts-node lock-token.ts",
|
||||
"submit-vaa": "ts-node submit-vaa.ts"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@terra-money/terra.js": "^0.5.12",
|
||||
"@types/node": "^14.14.6"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import { deploy_contract, instantiate_contract, query_contract } from './utils';
|
||||
|
||||
async function script() {
|
||||
const TEST_ADDRESS: string = 'terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v';
|
||||
// cw20_base.wasm is build from https://github.com/CosmWasm/cosmwasm-plus repository, v.0.2.0 and is a standard base cw20 contract
|
||||
let code_id = await deploy_contract('../artifacts/cw20_base.wasm');
|
||||
if (code_id == -1) return;
|
||||
console.log(`Program deployed with code id ${code_id}`);
|
||||
let contract_address = await instantiate_contract(code_id, {
|
||||
name: 'Test token',
|
||||
symbol: 'TST',
|
||||
decimals: 8,
|
||||
initial_balances: [{
|
||||
address: TEST_ADDRESS,
|
||||
amount: '100000000000000',
|
||||
}],
|
||||
mint: null,
|
||||
});
|
||||
console.log(`Contract instance created at ${contract_address}`);
|
||||
|
||||
// Verify if token was minted to the test address
|
||||
let result = await query_contract(contract_address, {balance: { address : TEST_ADDRESS}});
|
||||
console.log(`${TEST_ADDRESS} balance is ${result.balance}`);
|
||||
}
|
||||
|
||||
script();
|
|
@ -0,0 +1,26 @@
|
|||
import { deploy_contract, instantiate_contract, query_contract } from './utils';
|
||||
|
||||
async function script() {
|
||||
// Deploy cw20-wrapped
|
||||
let wrapped_code_id = await deploy_contract('../artifacts/cw20_wrapped.wasm');
|
||||
if (wrapped_code_id == -1) return;
|
||||
console.log(`CW20 Wrapped program deployed with code id ${wrapped_code_id}`);
|
||||
// Deploy wormhole
|
||||
let wormhole_code_id = await deploy_contract('../artifacts/wormhole.wasm');
|
||||
if (wormhole_code_id == -1) return;
|
||||
console.log(`Wormhole program deployed with code id ${wormhole_code_id}`);
|
||||
// Instantiate wormhole
|
||||
let contract_address = await instantiate_contract(wormhole_code_id, {
|
||||
initial_guardian_set: {
|
||||
addresses: [
|
||||
{ bytes: [0xbe, 0xfa, 0x42, 0x9d, 0x57, 0xcd, 0x18, 0xb7, 0xf8, 0xa4, 0xd9, 0x1a, 0x2d, 0xa9, 0xab, 0x4a, 0xf0, 0x5d, 0x0f, 0xbe] }
|
||||
],
|
||||
expiration_time: 1000 * 60 * 60
|
||||
},
|
||||
guardian_set_expirity: 0,
|
||||
wrapped_asset_code_id: wrapped_code_id,
|
||||
});
|
||||
console.log(`Wormhole instance created at ${contract_address}`);
|
||||
}
|
||||
|
||||
script();
|
|
@ -0,0 +1,17 @@
|
|||
import { execute_contract } from './utils';
|
||||
|
||||
async function script() {
|
||||
if (process.argv.length < 3) {
|
||||
console.log('Required 1 param WORMHOLE_CONTRACT');
|
||||
}
|
||||
let wormhole_contract = process.argv[2];
|
||||
|
||||
// Test VAA built using bridge/cmd/vaa-test
|
||||
let vaaResult = await execute_contract(wormhole_contract, {submit_v_a_a: {
|
||||
vaa: [...Buffer.from('010000000001005468beb21caff68710b2af2d60a986245bf85099509b6babe990a6c32456b44b3e2e9493e3056b7d5892957e14beab24be02dab77ed6c8915000e4a1267f78f400000007d01000000038018002010400000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000', 'hex')]
|
||||
}});
|
||||
if (vaaResult == null) return;
|
||||
console.log('Vaa submitted');
|
||||
}
|
||||
|
||||
script();
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"target": "es2017",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"outDir": "dist"
|
||||
},
|
||||
"lib": ["es2017"]
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
import { LCDClient, MsgStoreCode, MsgInstantiateContract, MsgExecuteContract, MnemonicKey, isTxError } from '@terra-money/terra.js';
|
||||
import * as fs from 'fs';
|
||||
|
||||
// test1 key from localterra accounts
|
||||
const mk = new MnemonicKey({
|
||||
mnemonic: 'notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius'
|
||||
})
|
||||
|
||||
// connect to localterra
|
||||
const terra = new LCDClient({
|
||||
URL: 'http://localhost:1317',
|
||||
chainID: 'localterra'
|
||||
});
|
||||
const wallet = terra.wallet(mk);
|
||||
|
||||
export async function deploy_contract(wasm_file) : Promise<number> {
|
||||
|
||||
const storeCode = new MsgStoreCode(
|
||||
wallet.key.accAddress,
|
||||
fs.readFileSync(wasm_file).toString('base64')
|
||||
);
|
||||
try {
|
||||
const storeCodeTx = await wallet.createAndSignTx({
|
||||
msgs: [storeCode],
|
||||
});
|
||||
const storeCodeTxResult = await terra.tx.broadcast(storeCodeTx);
|
||||
|
||||
//console.log(storeCodeTxResult);
|
||||
|
||||
if (isTxError(storeCodeTxResult)) {
|
||||
throw new Error(
|
||||
`store code failed. code: ${storeCodeTxResult.code}, codespace: ${storeCodeTxResult.codespace}, raw_log: ${storeCodeTxResult.raw_log}`
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
store_code: { code_id },
|
||||
} = storeCodeTxResult.logs[0].eventsByType;
|
||||
|
||||
return parseInt(code_id[0], 10);
|
||||
} catch (err) {
|
||||
console.log(`Error ${err}`);
|
||||
if (err.response) {
|
||||
console.log(err.response.data);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
export async function instantiate_contract(code_id: number, initMsg: object) : Promise<string> {
|
||||
try {
|
||||
const instantiate = new MsgInstantiateContract(
|
||||
wallet.key.accAddress,
|
||||
code_id,
|
||||
initMsg,
|
||||
{},
|
||||
false
|
||||
);
|
||||
|
||||
const instantiateTx = await wallet.createAndSignTx({
|
||||
msgs: [instantiate],
|
||||
});
|
||||
const instantiateTxResult = await terra.tx.broadcast(instantiateTx);
|
||||
|
||||
if (isTxError(instantiateTxResult)) {
|
||||
throw new Error(
|
||||
`instantiate failed. code: ${instantiateTxResult.code}, codespace: ${instantiateTxResult.codespace}, raw_log: ${instantiateTxResult.raw_log}`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
instantiate_contract: { contract_address },
|
||||
} = instantiateTxResult.logs[0].eventsByType;
|
||||
|
||||
return contract_address[0];
|
||||
|
||||
} catch (err) {
|
||||
console.log(`Error ${err}`);
|
||||
if (err.response) {
|
||||
console.log(err.response.data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function execute_contract(contract_address: string, msg: object) : Promise<any> {
|
||||
try {
|
||||
const execute = new MsgExecuteContract(
|
||||
wallet.key.accAddress,
|
||||
contract_address,
|
||||
{ ...msg }, { }
|
||||
);
|
||||
|
||||
const executeTx = await wallet.createAndSignTx({
|
||||
msgs: [execute]
|
||||
});
|
||||
|
||||
const result = await terra.tx.broadcast(executeTx);
|
||||
return result;
|
||||
} catch (err) {
|
||||
console.log(`Error ${err}`);
|
||||
if (err.response) {
|
||||
console.log(err.response.data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function query_contract(contract_address: string, query: object) : Promise<any> {
|
||||
const result = await terra.wasm.contractQuery(
|
||||
contract_address, query
|
||||
);
|
||||
return result;
|
||||
}
|
Loading…
Reference in New Issue