├── txDb ├── raw │ └── raw.md ├── signed │ └── signed.md ├── witness │ └── witness.md └── policy │ └── policy.script ├── tokens ├── iota │ ├── key.go │ ├── sendtx.go │ ├── register.go │ ├── tools │ │ ├── getStubChainID │ │ │ └── main.go │ │ ├── publicKeyToAddress │ │ │ └── main.go │ │ ├── keygen │ │ │ └── main.go │ │ └── sendMessage │ │ │ └── main.go │ ├── utils.go │ ├── type.go │ └── address.go ├── ripple │ ├── rubblelabs │ │ └── ripple │ │ │ ├── .travis.yml │ │ │ ├── data │ │ │ ├── memo.go │ │ │ ├── signing.go │ │ │ ├── interface.go │ │ │ ├── validation.go │ │ │ ├── util.go │ │ │ ├── proposal.go │ │ │ ├── reader.go │ │ │ ├── inner.go │ │ │ ├── ledger.go │ │ │ └── time.go │ │ │ ├── AUTHORS │ │ │ ├── crypto │ │ │ ├── interface.go │ │ │ ├── util.go │ │ │ ├── const.go │ │ │ ├── ed25519.go │ │ │ ├── hash_test.go │ │ │ ├── signature.go │ │ │ └── base58.go │ │ │ ├── .gitignore │ │ │ ├── config │ │ │ ├── action_test.go │ │ │ └── testdata │ │ │ │ └── test.json │ │ │ ├── LICENSE │ │ │ └── TODO.md │ ├── utils.go │ ├── register.go │ ├── tools │ │ ├── getStubChainID │ │ │ └── main.go │ │ └── publicKeyToAddress │ │ │ └── main.go │ ├── sendtx.go │ ├── README.md │ └── address.go ├── eth │ ├── doc.go │ ├── callapi │ │ ├── common.go │ │ ├── arbitrum.go │ │ ├── conflux.go │ │ └── kusama.go │ ├── routercontract.go │ └── sendtx.go ├── near │ ├── tools │ │ ├── deployContract │ │ │ └── mpc_pool.wasm │ │ ├── getStubChainID │ │ │ └── main.go │ │ ├── publicKeyToAddress │ │ │ └── main.go │ │ └── README.md │ ├── sendtx.go │ ├── key.go │ └── address.go ├── tron │ ├── routercontract.go │ ├── tools │ │ ├── publicKeyToAddress │ │ │ └── main.go │ │ ├── eth2tronAddress │ │ │ └── main.go │ │ └── tron2ethAddress │ │ │ └── main.go │ └── sendtx.go ├── flow │ ├── utils.go │ ├── types.go │ ├── tools │ │ ├── getStubChainID │ │ │ └── main.go │ │ └── scan │ │ │ └── main.go │ ├── transaction │ │ ├── SwapOut.cdc │ │ ├── Registry.cdc │ │ ├── SwapIn.cdc │ │ ├── Init.cdc │ │ └── CreateAccount.cdc │ ├── ReadMe_front_zh.md │ ├── sendtx.go │ ├── contracts │ │ └── AnyToken.cdc │ ├── key.go │ └── rpcclient.go ├── cosmos │ ├── utils.go │ ├── tools │ │ ├── publicKeyToAddress │ │ │ └── main.go │ │ ├── verifyAddress │ │ │ └── main.go │ │ └── getStubChainID │ │ │ └── main.go │ ├── sendtx.go │ ├── grpc │ │ └── retry │ │ │ └── retry.go │ └── README.md ├── cardano │ ├── utils.go │ ├── instance.go │ ├── tools │ │ ├── getStubChainID │ │ │ └── main.go │ │ ├── newToken │ │ │ └── main.go │ │ └── newWallet │ │ │ └── main.go │ ├── sendtx.go │ ├── address.go │ ├── cardanoCmd.go │ └── README_deployment.md ├── aptos │ ├── resource.go │ ├── tweetnacl │ │ ├── devurandom.h │ │ ├── doc.go │ │ ├── devurandom_windows.c │ │ ├── devurandom_darwin.c │ │ ├── devurandom_linux.c │ │ ├── util.go │ │ ├── tweetnacl_test.go │ │ ├── crypto_hash.go │ │ ├── scalarmult.go │ │ ├── crypto_verify.go │ │ └── crypto_auth.go │ ├── package.json │ ├── sendtx.go │ ├── tools │ │ ├── publicKeyToAddress │ │ │ └── main.go │ │ ├── getStubChainID │ │ │ └── main.go │ │ └── calcTxhashTest │ │ │ └── main.go │ └── ts_script.go ├── solana │ ├── tools │ │ ├── publicKeyToAddress │ │ │ └── main.go │ │ ├── genAccount │ │ │ └── main.go │ │ └── common.go │ ├── types │ │ ├── registry.go │ │ └── account.go │ └── address.go ├── stellar │ ├── tools │ │ ├── publicKeyToAddress │ │ │ └── main.go │ │ ├── addressToPublickey │ │ │ └── main.go │ │ ├── getStubChainID │ │ │ └── main.go │ │ └── buildSwapMemo │ │ │ └── main.go │ ├── README_frontend.md │ ├── sendtx.go │ ├── README.md │ ├── bridge_test.go │ └── address_test.go ├── reef │ ├── sendtx.go │ ├── tools │ │ ├── getStubChainID │ │ │ └── main.go │ │ ├── swapin │ │ │ └── main.go │ │ └── swapout │ │ │ └── main.go │ └── README_deployment.md ├── btc │ ├── tools │ │ ├── getStubChainID │ │ │ └── main.go │ │ ├── wifToEcPrivKey │ │ │ └── main.go │ │ └── pubKeyToAddress │ │ │ └── main.go │ ├── register.go │ ├── address.go │ ├── sendtx.go │ └── rpcclient.go ├── rpccall.go ├── tests │ ├── config │ │ └── config-test.toml │ └── README.md └── base │ └── reswapable.go ├── gofmt.sh ├── .github └── workflows │ ├── build-and-test.yml │ └── golangci-lint.yml ├── .gitignore ├── types ├── transaction_hash.go └── transaction_test.go ├── mongodb ├── tableinit.go ├── errors.go └── dbinit.go ├── mpc └── accept.go ├── worker ├── doc.go ├── worker.go ├── reportstat.go ├── utils.go └── aggregate.go ├── Makefile ├── params ├── config-sign-with-privatekey-example.toml └── version.go ├── cmd └── utils │ ├── versioncmd.go │ ├── licensecmd.go │ └── utils.go ├── tools ├── loadkeystore.go ├── rlp │ ├── encoder_example_test.go │ └── decode_tail_test.go └── weightedstring.go ├── admin └── utils.go ├── leveldb ├── batch.go ├── database.go └── iterator.go ├── common ├── hexutil │ └── json_example_test.go ├── size.go └── big.go ├── router └── bridge │ └── new.go └── log └── logger_test.go /txDb/raw/raw.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /txDb/signed/signed.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /txDb/witness/witness.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tokens/iota/key.go: -------------------------------------------------------------------------------- 1 | package iota 2 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - "1.10" -------------------------------------------------------------------------------- /tokens/eth/doc.go: -------------------------------------------------------------------------------- 1 | // Package eth implements the bridge interfaces to support routering. 2 | package eth 3 | -------------------------------------------------------------------------------- /txDb/policy/policy.script: -------------------------------------------------------------------------------- 1 | { 2 | "keyHash": "9659047006df5025d0b1103d6cc3d61244f6dd62259b891c1c87c072", 3 | "type": "sig" 4 | } -------------------------------------------------------------------------------- /tokens/near/tools/deployContract/mpc_pool.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anyswap/CrossChain-Router/HEAD/tokens/near/tools/deployContract/mpc_pool.wasm -------------------------------------------------------------------------------- /tokens/tron/routercontract.go: -------------------------------------------------------------------------------- 1 | package tron 2 | 3 | // GetPairFor call "getPair(address,address)" 4 | func (b *Bridge) GetPairFor(factory, token0, token1 string) (string, error) { 5 | return "", nil 6 | } 7 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/memo.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | type Memo struct { 4 | Memo struct { 5 | MemoType VariableLength 6 | MemoData VariableLength 7 | MemoFormat VariableLength 8 | } 9 | } 10 | 11 | type Memos []Memo 12 | -------------------------------------------------------------------------------- /tokens/flow/utils.go: -------------------------------------------------------------------------------- 1 | package flow 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | ) 7 | 8 | var ( 9 | FixLen = 8 10 | ) 11 | 12 | func ParseFlowNumber(amount *big.Int) string { 13 | value := amount.String() 14 | if len(value) <= FixLen { 15 | return "0." + fmt.Sprintf("%08d", amount) 16 | } 17 | return value[0:len(value)-FixLen] + "." + value[len(value)-FixLen:] 18 | } 19 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/AUTHORS: -------------------------------------------------------------------------------- 1 | # Names should be added to this file as 2 | # Name or Organization 3 | # The email address is not required for organizations. 4 | 5 | # Please keep the list sorted. 6 | 7 | Donovan Hide 8 | Luke Cyca -------------------------------------------------------------------------------- /gofmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find_files() { 4 | find . ! \( \ 5 | \( \ 6 | -path '.github' \ 7 | -o -path '.git' \ 8 | -o -path './bin' \ 9 | -o -path '*/vendor/*' \ 10 | \) -prune \ 11 | \) -name '*.go' 12 | } 13 | 14 | GOFMT="gofmt -s -w" 15 | GOIMPORTS="goimports -w" 16 | find_files | xargs $GOFMT 17 | find_files | xargs $GOIMPORTS 18 | -------------------------------------------------------------------------------- /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: 3 | push: 4 | pull_request: 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: actions/setup-go@v3 11 | with: 12 | go-version: '1.18' 13 | - run: | 14 | go run build/ci.go install ./cmd/... 15 | go build -v ./... 16 | go test ./... 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | build/ 18 | .vscode 19 | node_modules 20 | *.lock 21 | 22 | .idea/ 23 | .DS_Store -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/crypto/interface.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import "math/big" 4 | 5 | type Key interface { 6 | Private(*uint32) []byte 7 | Id(*uint32) []byte 8 | Public(*uint32) []byte 9 | } 10 | 11 | type Hash interface { 12 | Version() HashVersion 13 | Payload() []byte 14 | PayloadTrimmed() []byte 15 | Value() *big.Int 16 | String() string 17 | Clone() Hash 18 | MarshalText() ([]byte, error) 19 | } 20 | -------------------------------------------------------------------------------- /tokens/flow/types.go: -------------------------------------------------------------------------------- 1 | package flow 2 | 3 | import ( 4 | "github.com/onflow/cadence" 5 | ) 6 | 7 | type SwapIn struct { 8 | Tx cadence.String `json:"tx"` 9 | Token cadence.String `json:"token"` 10 | Receiver cadence.Address `json:"Receiver"` 11 | FromChainId cadence.UInt64 `json:"fromChainId"` 12 | Amount cadence.UFix64 `json:"amount"` 13 | ReceivePaths cadence.Array `json:"receivePaths"` 14 | } 15 | -------------------------------------------------------------------------------- /tokens/cosmos/utils.go: -------------------------------------------------------------------------------- 1 | package cosmos 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | func ParseCoinsNormalized(coinStr string) (sdk.Coins, error) { 8 | return sdk.ParseCoinsNormalized(coinStr) 9 | } 10 | 11 | func ParseCoinsFee(amount string) (sdk.Coins, error) { 12 | if parsedFees, err := sdk.ParseCoinsNormalized(amount); err != nil { 13 | return nil, err 14 | } else { 15 | return parsedFees, nil 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | 25 | *.out 26 | 27 | *.coverprofile 28 | 29 | .DS_Store 30 | -------------------------------------------------------------------------------- /tokens/cardano/utils.go: -------------------------------------------------------------------------------- 1 | package cardano 2 | 3 | import ( 4 | "crypto/ed25519" 5 | "encoding/hex" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | ) 9 | 10 | func StringToPrivateKey(priv string) (*ed25519.PrivateKey, error) { 11 | if data, err := hex.DecodeString(priv); err != nil { 12 | return nil, err 13 | } else { 14 | log.Info("StringToPrivateKey", "data", data) 15 | ed25519PriKey := ed25519.NewKeyFromSeed(data) 16 | return &ed25519PriKey, nil 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tokens/aptos/resource.go: -------------------------------------------------------------------------------- 1 | package aptos 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func (b *Bridge) IsNative(resource string) bool { 9 | return strings.Split(resource, "::")[0] == "0x1" 10 | } 11 | 12 | func GetRouterModelId(address, modelname string) string { 13 | return fmt.Sprintf("%s::%s", address, modelname) 14 | } 15 | 16 | func GetRouterFunctionId(address, modelname, function string) string { 17 | return fmt.Sprintf("%s::%s::%s", address, modelname, function) 18 | } 19 | -------------------------------------------------------------------------------- /tokens/ripple/utils.go: -------------------------------------------------------------------------------- 1 | package ripple 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/tokens/ripple/rubblelabs/ripple/data" 7 | ) 8 | 9 | // ParsePaths parse paths 10 | func ParsePaths(s string) (*data.PathSet, error) { 11 | ps := data.PathSet{} 12 | for _, pathStr := range strings.Split(s, ",") { 13 | path, err := data.NewPath(pathStr) 14 | if err != nil { 15 | return nil, err 16 | } 17 | ps = append(ps, path) 18 | } 19 | return &ps, nil 20 | } 21 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/config/action_test.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | func TestParse(t *testing.T) { 9 | f, err := os.Open("testdata/test.json") 10 | if err != nil { 11 | t.Fatalf("open file: %v", err) 12 | } 13 | defer f.Close() 14 | actions, err := Parse(f) 15 | if err != nil { 16 | t.Fatalf("parse: %v", err) 17 | } 18 | if err := actions.Prepare(); err != nil { 19 | t.Fatalf("prepare: %v", err) 20 | } 21 | t.Log(actions) 22 | } 23 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/devurandom.h: -------------------------------------------------------------------------------- 1 | /* 2 | randombytes/devurandom.h version 20080713 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #ifndef randombytes_devurandom_H 8 | #define randombytes_devurandom_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | extern void randombytes(unsigned char *,unsigned long long); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #ifndef randombytes_implementation 21 | #define randombytes_implementation "devurandom" 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /tokens/aptos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aptos-txhash", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "txhash": "node --loader ts-node/esm calc_tx_hash.ts" 7 | }, 8 | "keywords": [], 9 | "dependencies": { 10 | "aptos": "^1.3.14", 11 | "cross-fetch": "^3.1.5", 12 | "fmt": "^2.0.0", 13 | "js-sha3": "^0.8.0", 14 | "tweetnacl": "^1.0.3" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "^18.11.0", 18 | "ts-node": "^10.7.0", 19 | "typescript": "^4.6.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tokens/eth/callapi/common.go: -------------------------------------------------------------------------------- 1 | package callapi 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/common/hexutil" 5 | "github.com/anyswap/CrossChain-Router/v3/tokens" 6 | ) 7 | 8 | var ( 9 | wrapRPCQueryError = tokens.WrapRPCQueryError 10 | ) 11 | 12 | // EvmBridge evm bridge interface 13 | // import and use eth.Bridge will cause import cycle 14 | // so define a new interface here 15 | type EvmBridge interface { 16 | tokens.IBridge 17 | 18 | CallContract(contract string, data hexutil.Bytes, blockNumber string) (string, error) 19 | } 20 | -------------------------------------------------------------------------------- /tokens/cardano/instance.go: -------------------------------------------------------------------------------- 1 | package cardano 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/tokens" 5 | ) 6 | 7 | // BridgeInstance btc bridge instance 8 | var BridgeInstance BridgeInterface 9 | 10 | // BridgeInterface btc bridge interface 11 | type BridgeInterface interface { 12 | tokens.IBridge 13 | 14 | QueryUtxoOnChain(address string) (map[UtxoKey]AssetsMap, error) 15 | BuildAggregateTx(swapId string, utxos map[UtxoKey]AssetsMap) (*RawTransaction, error) 16 | AggregateTx() (string, error) 17 | VerifyAggregate(msgHash []string, args *tokens.BuildTxArgs) error 18 | } 19 | -------------------------------------------------------------------------------- /tokens/solana/tools/publicKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | "github.com/anyswap/CrossChain-Router/v3/tokens/solana" 9 | ) 10 | 11 | var ( 12 | paramPubKey string 13 | ) 14 | 15 | func initFlags() { 16 | flag.StringVar(¶mPubKey, "p", "", "public key hex string") 17 | 18 | flag.Parse() 19 | } 20 | 21 | func main() { 22 | log.SetLogger(6, false, true) 23 | initFlags() 24 | addr, err := solana.PublicKeyToAddress(paramPubKey) 25 | if err != nil { 26 | log.Fatalf("%v", err) 27 | } 28 | fmt.Printf("address: %v\n", addr) 29 | } 30 | -------------------------------------------------------------------------------- /tokens/aptos/sendtx.go: -------------------------------------------------------------------------------- 1 | package aptos 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/log" 7 | ) 8 | 9 | // SendTransaction impl 10 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 11 | tx, ok := signedTx.(*Transaction) 12 | if !ok { 13 | return "", errors.New("wrong signed transaction type") 14 | } 15 | txInfo, err := b.SubmitTranscation(tx) 16 | if err != nil { 17 | log.Info("Aptos SendTransaction failed", "err", err) 18 | return "", err 19 | } else { 20 | log.Info("Aptos SendTransaction success", "hash", txInfo.Hash) 21 | } 22 | return txInfo.Hash, err 23 | } 24 | -------------------------------------------------------------------------------- /tokens/aptos/tools/publicKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | "github.com/anyswap/CrossChain-Router/v3/tokens/aptos" 9 | ) 10 | 11 | var ( 12 | paramPubKey string 13 | ) 14 | 15 | func initFlags() { 16 | flag.StringVar(¶mPubKey, "p", "", "public key hex string") 17 | 18 | flag.Parse() 19 | } 20 | 21 | func main() { 22 | log.SetLogger(6, false, true) 23 | 24 | initFlags() 25 | 26 | addr, err := aptos.PublicKeyToAddress(paramPubKey) 27 | if err != nil { 28 | log.Fatalf("%v", err) 29 | } 30 | fmt.Printf("address: %v\n", addr) 31 | } 32 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | tweetnacl-go is a port of Dan Bernstein's "crypto library in a 100 tweets" code to the Go language. 3 | It is implemented as a wrapper around the original code to preserve the design and timing 4 | characteristics of the original implementation. 5 | 6 | The Go wrapper has been kept as 'thin' as possible to avoid compromising the careful design 7 | and coding of the original TweetNaCl implementation. However, cryptography being what it is, 8 | the wrapper may have (entirely inadvertently) introduced non-obvious vulnerabilities (for 9 | instance. 10 | 11 | http://tweetnacl.cr.yp.to 12 | */ 13 | package tweetnacl 14 | -------------------------------------------------------------------------------- /tokens/stellar/tools/publicKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | "github.com/anyswap/CrossChain-Router/v3/tokens/stellar" 9 | ) 10 | 11 | var ( 12 | paramPubKey string 13 | ) 14 | 15 | func initFlags() { 16 | flag.StringVar(¶mPubKey, "p", "", "public key string") 17 | 18 | flag.Parse() 19 | } 20 | 21 | func main() { 22 | log.SetLogger(6, false, true) 23 | 24 | initFlags() 25 | 26 | addr, err := stellar.PublicKeyHexToAddress(paramPubKey) 27 | if err != nil { 28 | log.Fatalf("%v", err) 29 | } 30 | fmt.Printf("address: %v\n", addr) 31 | } 32 | -------------------------------------------------------------------------------- /types/transaction_hash.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/common" 5 | ) 6 | 7 | // Hash returns the transaction hash 8 | func (tx *Transaction) Hash() common.Hash { 9 | if hash := tx.hash.Load(); hash != nil { 10 | return hash.(common.Hash) 11 | } 12 | var h common.Hash 13 | switch tx.Type() { 14 | case LegacyTxType: 15 | h = rlpHash(tx.toLegacyTx()) 16 | case AccessListTxType: 17 | h = prefixedRlpHash(tx.Type(), tx.toAccessListTx()) 18 | case DynamicFeeTxType: 19 | h = prefixedRlpHash(tx.Type(), tx.toDynamicFeeTx()) 20 | } 21 | if h != common.EmptyHash { 22 | tx.hash.Store(h) 23 | } 24 | return h 25 | } 26 | -------------------------------------------------------------------------------- /tokens/iota/sendtx.go: -------------------------------------------------------------------------------- 1 | package iota 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/log" 5 | "github.com/anyswap/CrossChain-Router/v3/tokens" 6 | iotago "github.com/iotaledger/iota.go/v2" 7 | ) 8 | 9 | // SendTransaction send signed tx 10 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 11 | message := signedTx.(*iotago.Message) 12 | urls := b.GetGatewayConfig().AllGatewayURLs 13 | for _, url := range urls { 14 | if txHash, err = CommitMessage(url, message); err == nil { 15 | return txHash, nil 16 | } else { 17 | log.Warn("CommitMessage", "err", err) 18 | } 19 | } 20 | return "", tokens.ErrCommitMessage 21 | } 22 | -------------------------------------------------------------------------------- /mongodb/tableinit.go: -------------------------------------------------------------------------------- 1 | package mongodb 2 | 3 | import ( 4 | "go.mongodb.org/mongo-driver/mongo" 5 | ) 6 | 7 | const ( 8 | tbRouterSwaps string = "RouterSwaps" 9 | tbRouterSwapResults string = "RouterSwapResults" 10 | tbUsedRValues string = "UsedRValues" 11 | ) 12 | 13 | var ( 14 | collRouterSwap *mongo.Collection 15 | collRouterSwapResult *mongo.Collection 16 | collUsedRValue *mongo.Collection 17 | ) 18 | 19 | func initCollections() { 20 | database := client.Database(databaseName) 21 | 22 | collRouterSwap = database.Collection(tbRouterSwaps) 23 | collRouterSwapResult = database.Collection(tbRouterSwapResults) 24 | collUsedRValue = database.Collection(tbUsedRValues) 25 | } 26 | -------------------------------------------------------------------------------- /tokens/reef/sendtx.go: -------------------------------------------------------------------------------- 1 | package reef 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "log" 7 | "strings" 8 | ) 9 | 10 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 11 | tx, ok := signedTx.(*ReefTransaction) 12 | if !ok { 13 | log.Printf("signed tx is %+v", signedTx) 14 | return "", errors.New("wrong signed transaction type") 15 | } 16 | 17 | txHash, err = SendSignedTx(tx.buildScriptParam()) 18 | if err != nil { 19 | return "", err 20 | } 21 | if !strings.EqualFold(*tx.TxHash, txHash) { 22 | return "", fmt.Errorf("txhash dismatch txHash %s sendTx %s", *tx.TxHash, txHash) 23 | } 24 | b.SetNonce(*tx.ReefAddress, *tx.AccountNonce+1) 25 | return txHash, nil 26 | } 27 | -------------------------------------------------------------------------------- /tokens/solana/tools/genAccount/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/log" 7 | "github.com/anyswap/CrossChain-Router/v3/tokens/solana/types" 8 | ) 9 | 10 | func main() { 11 | log.SetLogger(6, false, true) 12 | mintPublicKey, mintPriKey, _ := types.NewRandomPrivateKey() 13 | fmt.Printf("PriKey bytes: [") 14 | for i := 0; i < len(mintPriKey); i++ { 15 | if i == len(mintPriKey)-1 { 16 | fmt.Printf("%v", mintPriKey[i]) 17 | } else { 18 | fmt.Printf("%v, ", mintPriKey[i]) 19 | } 20 | } 21 | fmt.Printf("] \n") 22 | fmt.Printf("PriKey(base58): %v\n", mintPriKey.String()) 23 | fmt.Printf("Address(base58): %v\n", mintPublicKey.String()) 24 | } 25 | -------------------------------------------------------------------------------- /tokens/cosmos/tools/publicKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | "github.com/anyswap/CrossChain-Router/v3/tokens/cosmos" 9 | ) 10 | 11 | var ( 12 | paramPublicKey string 13 | paramPrefix string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mPublicKey, "p", "", "publicKey") 18 | flag.StringVar(¶mPrefix, "prefix", "", "prefix, eg. cosmos, sei, etc.") 19 | 20 | flag.Parse() 21 | } 22 | 23 | func main() { 24 | initFlags() 25 | 26 | if addr, err := cosmos.PublicKeyToAddress(paramPrefix, paramPublicKey); err != nil { 27 | log.Fatalf("err: %v\n", err) 28 | } else { 29 | fmt.Printf("addr: %v\n", addr) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tokens/stellar/tools/addressToPublickey/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "flag" 6 | "fmt" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/stellar/go/strkey" 10 | ) 11 | 12 | var ( 13 | paramAddress string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mAddress, "a", "", "address string") 18 | flag.Parse() 19 | } 20 | 21 | func main() { 22 | log.SetLogger(6, false, true) 23 | 24 | initFlags() 25 | fmt.Printf("address: %v\n", paramAddress) 26 | publicKey, err := strkey.Decode(strkey.VersionByteAccountID, paramAddress) 27 | if err != nil { 28 | log.Fatalf("%v", err) 29 | } 30 | pub := hex.EncodeToString(publicKey) 31 | 32 | fmt.Printf("publickey: %v\n", pub) 33 | } 34 | -------------------------------------------------------------------------------- /tokens/iota/register.go: -------------------------------------------------------------------------------- 1 | package iota 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/tokens" 5 | ) 6 | 7 | // RegisterSwap api 8 | func (b *Bridge) RegisterSwap(txHash string, args *tokens.RegisterArgs) ([]*tokens.SwapTxInfo, []error) { 9 | swapType := args.SwapType 10 | logIndex := args.LogIndex 11 | 12 | switch swapType { 13 | case tokens.ERC20SwapType: 14 | return b.registerERC20SwapTx(txHash, logIndex) 15 | default: 16 | return nil, []error{tokens.ErrSwapTypeNotSupported} 17 | } 18 | } 19 | 20 | func (b *Bridge) registerERC20SwapTx(txHash string, logIndex int) ([]*tokens.SwapTxInfo, []error) { 21 | swapInfo, err := b.verifySwapoutTx(txHash, logIndex, true) 22 | return []*tokens.SwapTxInfo{swapInfo}, []error{err} 23 | } 24 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/devurandom_windows.c: -------------------------------------------------------------------------------- 1 | // +build windows,cgo 2 | 3 | #include 4 | #include 5 | 6 | #pragma comment(lib, "crypt32.lib") 7 | 8 | void randombytes(unsigned char * a,unsigned long long c) { 9 | HCRYPTPROV hProvider = 0; 10 | while (1) { 11 | if (!CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { 12 | Sleep(1); 13 | continue; 14 | } 15 | 16 | if (!CryptGenRandom(hProvider, (DWORD)c, (BYTE*)a)) { 17 | CryptReleaseContext(hProvider, 0); 18 | Sleep(1); 19 | continue; 20 | } 21 | 22 | CryptReleaseContext(hProvider, 0); 23 | break; 24 | } 25 | } -------------------------------------------------------------------------------- /tokens/ripple/register.go: -------------------------------------------------------------------------------- 1 | package ripple 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/tokens" 5 | ) 6 | 7 | // RegisterSwap api 8 | func (b *Bridge) RegisterSwap(txHash string, args *tokens.RegisterArgs) ([]*tokens.SwapTxInfo, []error) { 9 | swapType := args.SwapType 10 | logIndex := args.LogIndex 11 | 12 | switch swapType { 13 | case tokens.ERC20SwapType: 14 | return b.registerERC20SwapTx(txHash, logIndex) 15 | default: 16 | return nil, []error{tokens.ErrSwapTypeNotSupported} 17 | } 18 | } 19 | 20 | func (b *Bridge) registerERC20SwapTx(txHash string, logIndex int) ([]*tokens.SwapTxInfo, []error) { 21 | swapInfo, err := b.verifySwapoutTx(txHash, logIndex, true) 22 | return []*tokens.SwapTxInfo{swapInfo}, []error{err} 23 | } 24 | -------------------------------------------------------------------------------- /tokens/cosmos/tools/verifyAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/tokens/cosmos" 8 | ) 9 | 10 | var ( 11 | paramPrefix string 12 | paramAddress string 13 | ) 14 | 15 | func initFlags() { 16 | flag.StringVar(¶mPrefix, "prefix", "", "prefix, eg. cosmos, sei, etc.") 17 | flag.StringVar(¶mAddress, "address", "", "address") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | initFlags() 24 | 25 | res := cosmos.IsValidAddress(paramPrefix, paramAddress) 26 | if res { 27 | fmt.Printf("address %s is valid (prefix: %v)\n", paramAddress, paramPrefix) 28 | } else { 29 | fmt.Printf("address %s is invalid (prefix: %v)\n", paramAddress, paramPrefix) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Donovan Hide 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/devurandom_darwin.c: -------------------------------------------------------------------------------- 1 | // +build darwin,cgo 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /* it's really stupid that there isn't a syscall for this */ 9 | 10 | static int fd = -1; 11 | 12 | void randombytes(unsigned char *x,unsigned long long xlen) 13 | { 14 | int i; 15 | 16 | if (fd == -1) { 17 | for (;;) { 18 | fd = open("/dev/urandom",O_RDONLY); 19 | if (fd != -1) break; 20 | sleep(1); 21 | } 22 | } 23 | 24 | while (xlen > 0) { 25 | if (xlen < 1048576) i = xlen; else i = 1048576; 26 | 27 | i = read(fd,x,i); 28 | if (i < 1) { 29 | sleep(1); 30 | continue; 31 | } 32 | 33 | x += i; 34 | xlen -= i; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/devurandom_linux.c: -------------------------------------------------------------------------------- 1 | // +build linux,cgo 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /* it's really stupid that there isn't a syscall for this */ 9 | 10 | static int fd = -1; 11 | 12 | void randombytes(unsigned char *x,unsigned long long xlen) 13 | { 14 | int i; 15 | 16 | if (fd == -1) { 17 | for (;;) { 18 | fd = open("/dev/urandom",O_RDONLY); 19 | if (fd != -1) break; 20 | sleep(1); 21 | } 22 | } 23 | 24 | while (xlen > 0) { 25 | if (xlen < 1048576) i = xlen; else i = 1048576; 26 | 27 | i = read(fd,x,i); 28 | if (i < 1) { 29 | sleep(1); 30 | continue; 31 | } 32 | 33 | x += i; 34 | xlen -= i; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mpc/accept.go: -------------------------------------------------------------------------------- 1 | package mpc 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/common" 7 | ) 8 | 9 | // DoAcceptSign accept sign 10 | func (c *Config) DoAcceptSign(keyID, agreeResult string, msgHash, msgContext []string) (string, error) { 11 | nonce := uint64(0) 12 | data := AcceptData{ 13 | TxType: "ACCEPTSIGN", 14 | Key: keyID, 15 | Accept: agreeResult, 16 | MsgHash: msgHash, 17 | MsgContext: msgContext, 18 | TimeStamp: common.NowMilliStr(), 19 | } 20 | payload, err := json.Marshal(data) 21 | if err != nil { 22 | return "", err 23 | } 24 | rawTX, err := BuildMPCRawTx(nonce, payload, c.defaultMPCNode.keyWrapper) 25 | if err != nil { 26 | return "", err 27 | } 28 | return c.AcceptSign(rawTX) 29 | } 30 | -------------------------------------------------------------------------------- /tokens/flow/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/flow" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | log.Fatal("miss network argument") 33 | } 34 | 35 | chainID := flow.GetStubChainID(network) 36 | fmt.Printf("%v: %v\n", network, chainID) 37 | } 38 | -------------------------------------------------------------------------------- /tokens/near/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/near" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | log.Fatal("miss network argument") 33 | } 34 | 35 | chainID := near.GetStubChainID(network) 36 | fmt.Printf("%v: %v\n", network, chainID) 37 | } 38 | -------------------------------------------------------------------------------- /tokens/btc/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/btc" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, devnet, etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | log.Fatal("miss network argument") 33 | } 34 | 35 | chainID := btc.GetStubChainID(network) 36 | fmt.Printf("%v: %v\n", network, chainID) 37 | } 38 | -------------------------------------------------------------------------------- /tokens/cardano/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/cardano" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | log.Fatal("miss network argument") 33 | } 34 | 35 | chainID := cardano.GetStubChainID(network) 36 | fmt.Printf("%v: %v\n", network, chainID) 37 | } 38 | -------------------------------------------------------------------------------- /tokens/iota/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/iota" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, devnet, etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | log.Fatal("miss network argument") 33 | } 34 | 35 | chainID := iota.GetStubChainID(network) 36 | fmt.Printf("%v: %v\n", network, chainID) 37 | } 38 | -------------------------------------------------------------------------------- /tokens/stellar/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/stellar" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | log.Fatal("miss network argument") 33 | } 34 | 35 | chainID := stellar.GetStubChainID(network) 36 | fmt.Printf("%v: %v\n", network, chainID) 37 | } 38 | -------------------------------------------------------------------------------- /tokens/ripple/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/ripple" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, devnet, etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | log.Fatal("miss network argument") 33 | } 34 | 35 | chainID := ripple.GetStubChainID(network) 36 | fmt.Printf("%v: %v\n", network, chainID) 37 | } 38 | -------------------------------------------------------------------------------- /worker/doc.go: -------------------------------------------------------------------------------- 1 | // Package worker includes all the tasks and jobs to process router swaps. 2 | // 3 | // It contains the following main steps (concurrently): 4 | // verify 5 | // verify registered swaps. 6 | // swap 7 | // build swaptx, mpc sign the tx, and send the tx to blockchain. 8 | // accept 9 | // the `oracle` node do the accept job, agree or disagree the signing after verifying by oralce itself. 10 | // stable 11 | // mark swap status to `stabe` status. 12 | // replace 13 | // replace swap with the same tx nonce value when the sent swaptx is not packed into block because of lack fee or other reasons. 14 | // passbigvalue 15 | // pass big value swap if the swap value is too large. 16 | // Most the above jobs is assigned to the `server` node, the `oracle` node mainly do the `accept` job. 17 | package worker 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all test testv clean fmt 2 | .PHONY: swaprouter 3 | 4 | GOBIN = ./build/bin 5 | GOCMD = env GO111MODULE=on GOPROXY=https://goproxy.io,direct go 6 | 7 | swaprouter: 8 | $(GOCMD) run build/ci.go install ./cmd/swaprouter 9 | @echo "Done building." 10 | @echo "Run \"$(GOBIN)/swaprouter\" to launch swaprouter." 11 | 12 | all: 13 | $(GOCMD) build -v ./... 14 | $(GOCMD) run build/ci.go install ./cmd/... 15 | @echo "Done building." 16 | @echo "Find binaries in \"$(GOBIN)\" directory." 17 | @echo "" 18 | @echo "Copy example config files to \"$(GOBIN)\" directory" 19 | @cp -uv params/config*-example.toml $(GOBIN) 20 | 21 | test: all 22 | $(GOCMD) test ./... 23 | 24 | testv: all 25 | $(GOCMD) test -v ./... 26 | 27 | clean: 28 | $(GOCMD) clean -cache 29 | rm -fr $(GOBIN)/* 30 | 31 | fmt: 32 | ./gofmt.sh 33 | -------------------------------------------------------------------------------- /tokens/tron/tools/publicKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/tron" 10 | ) 11 | 12 | var ( 13 | paramPubKey string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mPubKey, "p", "", "public key string") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | pubkey := paramPubKey 28 | if pubkey == "" && len(os.Args) > 1 { 29 | pubkey = os.Args[1] 30 | } 31 | if pubkey == "" { 32 | log.Fatal("miss public key argument") 33 | } 34 | 35 | addr, err := tron.PubKeyToAddress(pubkey) 36 | if err != nil { 37 | log.Fatalf("%v", err) 38 | } 39 | fmt.Printf("address: %v\n", addr) 40 | } 41 | -------------------------------------------------------------------------------- /tokens/cardano/sendtx.go: -------------------------------------------------------------------------------- 1 | package cardano 2 | 3 | import "github.com/anyswap/CrossChain-Router/v3/log" 4 | 5 | // SendTransaction send signed tx 6 | func (b *Bridge) SendTransaction(signedTx interface{}) (string, error) { 7 | signedTransaction := signedTx.(*SignedTransaction) 8 | 9 | txhash, err := b.RpcClient.SubmitTx(signedTransaction.Tx) 10 | if err != nil { 11 | return "", err 12 | } 13 | log.Info("CardanoSubmitTx", "txhash", txhash.String(), "savedTxHash", signedTransaction.TxHash) 14 | 15 | TransactionChaining.InputKey.TxHash = signedTransaction.TxHash 16 | TransactionChaining.InputKey.TxIndex = signedTransaction.TxIndex 17 | TransactionChaining.AssetsMap = signedTransaction.AssetsMap 18 | AddTransactionChainingKeyCache(signedTransaction.TxHash, &signedTransaction.TxIns) 19 | return signedTransaction.TxHash, nil 20 | } 21 | -------------------------------------------------------------------------------- /tokens/ripple/tools/publicKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/ripple" 10 | ) 11 | 12 | var ( 13 | paramPubKey string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mPubKey, "p", "", "public key string") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | pubkey := paramPubKey 28 | if pubkey == "" && len(os.Args) > 1 { 29 | pubkey = os.Args[1] 30 | } 31 | if pubkey == "" { 32 | log.Fatal("miss public key argument") 33 | } 34 | 35 | addr, err := ripple.PublicKeyHexToAddress(pubkey) 36 | if err != nil { 37 | log.Fatalf("%v", err) 38 | } 39 | fmt.Printf("address: %v\n", addr) 40 | } 41 | -------------------------------------------------------------------------------- /tokens/tron/sendtx.go: -------------------------------------------------------------------------------- 1 | package tron 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | "github.com/fbsobreira/gotron-sdk/pkg/proto/core" 8 | 9 | "github.com/anyswap/CrossChain-Router/v3/log" 10 | ) 11 | 12 | // SendTransaction send signed tx 13 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 14 | tx, ok := signedTx.(*core.Transaction) 15 | if !ok { 16 | fmt.Printf("signed tx is %+v\n", signedTx) 17 | return "", errors.New("wrong signed transaction type") 18 | } 19 | txHash = CalcTxHash(tx) 20 | err = b.BroadcastTx(tx) 21 | if err != nil { 22 | log.Info("SendTransaction failed", "hash", txHash, "err", err) 23 | return txHash, err 24 | } 25 | log.Info("SendTransaction success", "hash", txHash) 26 | //#log.Trace("SendTransaction success", "raw", tx.RawStr()) 27 | return txHash, nil 28 | } 29 | -------------------------------------------------------------------------------- /tokens/tron/tools/eth2tronAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/tron" 10 | ) 11 | 12 | var ( 13 | paramEthAddress string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mEthAddress, "ethAddr", "", "eth address") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | ethAddress := paramEthAddress 28 | if ethAddress == "" && len(os.Args) > 1 { 29 | ethAddress = os.Args[1] 30 | } 31 | if ethAddress == "" { 32 | log.Fatal("miss eth address argument") 33 | } 34 | 35 | tronAddr, err := tron.EthToTron(ethAddress) 36 | if err != nil { 37 | log.Fatalf("%v", err) 38 | } 39 | 40 | fmt.Printf("eth address: %v\n", tronAddr) 41 | } 42 | -------------------------------------------------------------------------------- /tokens/btc/register.go: -------------------------------------------------------------------------------- 1 | package btc 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/log" 5 | "github.com/anyswap/CrossChain-Router/v3/tokens" 6 | ) 7 | 8 | // RegisterSwap api 9 | func (b *Bridge) RegisterSwap(txHash string, args *tokens.RegisterArgs) ([]*tokens.SwapTxInfo, []error) { 10 | swapType := args.SwapType 11 | logIndex := args.LogIndex 12 | 13 | switch swapType { 14 | case tokens.ERC20SwapType: 15 | return b.registerERC20SwapTx(txHash, logIndex) 16 | default: 17 | return nil, []error{tokens.ErrSwapTypeNotSupported} 18 | } 19 | } 20 | 21 | func (b *Bridge) registerERC20SwapTx(txHash string, logIndex int) ([]*tokens.SwapTxInfo, []error) { 22 | log.Info("registerERC20SwapTx", "txhash:", txHash, "logIndex:", logIndex) 23 | swapInfo, err := b.verifySwapoutTx(txHash, logIndex, true) 24 | return []*tokens.SwapTxInfo{swapInfo}, []error{err} 25 | } 26 | -------------------------------------------------------------------------------- /tokens/flow/transaction/SwapOut.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | import AnyExampleToken from %s 3 | import Router from %s 4 | 5 | transaction(token:String,to:String,toChainId:UInt64,value:UFix64) { 6 | let vaultRef: &{FungibleToken.Provider} 7 | let vaultStoragePath:StoragePath 8 | prepare(acct: AuthAccount) { 9 | self.vaultStoragePath= /storage/exampleTokenVault 10 | self.vaultRef = acct.borrow<&{FungibleToken.Provider}>(from:self.vaultStoragePath) 11 | ?? panic("Could not borrow a reference to the owner's vault") 12 | } 13 | 14 | execute { 15 | log("vaultStoragePath:".concat(self.vaultStoragePath.toString())) 16 | let temporaryVault <- self.vaultRef.withdraw(amount: value) 17 | Router.swapOut(token:token,to:to,toChainId:toChainId,value:<-temporaryVault) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tokens/tron/tools/tron2ethAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/tron" 10 | ) 11 | 12 | var ( 13 | paramTronAddress string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mTronAddress, "tronAddr", "", "tron address (base58 encoded)") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | tronAddress := paramTronAddress 28 | if tronAddress == "" && len(os.Args) > 1 { 29 | tronAddress = os.Args[1] 30 | } 31 | if tronAddress == "" { 32 | log.Fatal("miss tron address argument") 33 | } 34 | 35 | ethAddr, err := tron.TronToEth(tronAddress) 36 | if err != nil { 37 | log.Fatalf("%v", err) 38 | } 39 | 40 | fmt.Printf("eth address: %v\n", ethAddr) 41 | } 42 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/util.go: -------------------------------------------------------------------------------- 1 | package tweetnacl 2 | 3 | import ( 4 | "C" 5 | "reflect" 6 | "unsafe" 7 | ) 8 | 9 | // Convenience function to convert a byte array (or slice) to a 'C' pointer. The 10 | // function handles the zero length array case, which the normal version doesn't - 11 | // i.e. (*C.uchar)(unsafe.Pointer(&msg[0])) will crash with a panic when msg is a 12 | // zero length array. 13 | // 14 | // The commented out version which returns nil for a zero length array is somewhat 15 | // less bizarre and works as well. 16 | // 17 | // Ref. https://groups.google.com/forum/#!topic/golang-nuts/NNBdjztWquo 18 | // 19 | func makePtr(array []byte) *C.uchar { 20 | return (*C.uchar)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&array)).Data)) 21 | 22 | // if len(array) == 0 { 23 | // return nil 24 | // } else { 25 | // return (*C.uchar)(unsafe.Pointer(&array[0])) 26 | // } 27 | } 28 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/tweetnacl_test.go: -------------------------------------------------------------------------------- 1 | package tweetnacl 2 | 3 | import ( 4 | "bytes" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func verify(t *testing.T, description string, expected, result []byte, err error) { 10 | padding := strings.Repeat(" ", len(description)) 11 | 12 | if err != nil { 13 | t.Errorf("\n%v", err) 14 | return 15 | } 16 | 17 | if result == nil { 18 | t.Errorf("\n%s - expected %x\n%s - got: nil", description, expected, padding) 19 | return 20 | } 21 | 22 | if !bytes.Equal(result, expected) { 23 | t.Errorf("\n%s - expected %x\n%s - got: %x", description, expected, padding, result) 24 | return 25 | } 26 | } 27 | 28 | func verifyErr(t *testing.T, description string, result []byte, err error) { 29 | if err == nil { 30 | t.Errorf("\nExpected error (%s)", description) 31 | } 32 | 33 | if result != nil { 34 | t.Errorf("\nExpected error (%s)", description) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tokens/reef/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/reef" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, devnet, etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | for _, v := range []string{"mainnet", "testnet", "devnet"} { 33 | chainID := reef.GetStubChainID(v) 34 | fmt.Printf("%v: %v\n", v, chainID) 35 | } 36 | } else { 37 | chainID := reef.GetStubChainID(network) 38 | fmt.Printf("%v: %v\n", network, chainID) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tokens/aptos/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/aptos" 10 | ) 11 | 12 | var ( 13 | paramNetwork string 14 | ) 15 | 16 | func initFlags() { 17 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, devnet, etc.") 18 | 19 | flag.Parse() 20 | } 21 | 22 | func main() { 23 | log.SetLogger(6, false, true) 24 | 25 | initFlags() 26 | 27 | network := paramNetwork 28 | if network == "" && len(os.Args) > 1 { 29 | network = os.Args[1] 30 | } 31 | if network == "" { 32 | for _, v := range []string{"mainnet", "testnet", "devnet"} { 33 | chainID := aptos.GetStubChainID(v) 34 | fmt.Printf("%v: %v\n", v, chainID) 35 | } 36 | } else { 37 | chainID := aptos.GetStubChainID(network) 38 | fmt.Printf("%v: %v\n", network, chainID) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tokens/btc/address.go: -------------------------------------------------------------------------------- 1 | package btc 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/common" 5 | ) 6 | 7 | // IsValidAddress check address 8 | func (b *Bridge) IsValidAddress(address string) bool { 9 | _, err := b.DecodeAddress(address) 10 | return err == nil 11 | } 12 | 13 | // PublicKeyToAddress impl 14 | func (b *Bridge) PublicKeyToAddress(pubKey string) (string, error) { 15 | pkData := common.FromHex(pubKey) 16 | cPkData, err := b.ToCompressedPublicKey(pkData) 17 | if err != nil { 18 | return "", err 19 | } 20 | address, err := b.NewAddressPubKeyHash(cPkData) 21 | if err != nil { 22 | return "", err 23 | } 24 | return address.EncodeAddress(), nil 25 | } 26 | 27 | // todo: read from config 28 | func (b *Bridge) VerifyPubKey(address, pubKey string) error { 29 | wantAddr, err := b.PublicKeyToAddress(pubKey) 30 | if err != nil || wantAddr != address { 31 | return err 32 | } 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /tokens/btc/tools/wifToEcPrivKey/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/hex" 5 | "flag" 6 | "fmt" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/btc" 10 | ) 11 | 12 | var ( 13 | paramWif string 14 | paramChainID string 15 | ) 16 | 17 | func initFlags() { 18 | flag.StringVar(¶mWif, "wif", "", "wif") 19 | flag.StringVar(¶mChainID, "chainID", "", "chainID") 20 | 21 | flag.Parse() 22 | } 23 | 24 | func main() { 25 | log.SetLogger(6, false, true) 26 | 27 | initFlags() 28 | 29 | if paramWif == "" { 30 | log.Fatal("miss network argument") 31 | } 32 | 33 | wifPd, err := btc.DecodeWIF(paramWif) 34 | if err != nil { 35 | log.Fatal("DecodeWIF fails", "paramWif", paramWif) 36 | } 37 | ecPrikey := wifPd.PrivKey.ToECDSA() 38 | priString := hex.EncodeToString(ecPrikey.D.Bytes()) 39 | fmt.Printf("%v: %v:\n", paramWif, priString) 40 | } 41 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/config/testdata/test.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "seed": "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", 4 | "fee": "10000", 5 | "payments": [ 6 | { 7 | "sequence":1, 8 | "destination": "rb1fWuuAEtPUaeEWxocV3h4x5JwDTFZzH", 9 | "amount": "2000000000" 10 | }, 11 | { 12 | "sequence":2, 13 | "destination": "rb2L6Ujzku4hQWiCYyJQZJD9A1qEsUz5g", 14 | "amount": "2000000000" 15 | }, 16 | { 17 | "sequence":3, 18 | "destination": "rb3Kd8w5Ego7VeGnduFXm8Tw9dpi37v3A", 19 | "amount": "2000000000" 20 | }, 21 | { 22 | "sequence":4, 23 | "destination": "rb4S2wP8MP6c82XpkVQ2MHUt3Wop7fRvT", 24 | "amount": "2000000000" 25 | }, 26 | { 27 | "sequence":5, 28 | "destination": "rb3Kd8w5Ego7VeGnduFXm8Tw9dpi37v3A", 29 | "amount": "2000000000" 30 | } 31 | ] 32 | } 33 | ] -------------------------------------------------------------------------------- /tokens/aptos/ts_script.go: -------------------------------------------------------------------------------- 1 | package aptos 2 | 3 | import ( 4 | "fmt" 5 | "path/filepath" 6 | "runtime" 7 | "strings" 8 | 9 | "github.com/anyswap/CrossChain-Router/v3/common" 10 | ) 11 | 12 | func CurrentCallerDir() string { 13 | _, file, _, ok := runtime.Caller(0) 14 | if ok { 15 | return filepath.Dir(file) 16 | } 17 | return "" 18 | } 19 | 20 | func InstallTsModules() { 21 | common.MustRunBashCommand(CurrentCallerDir(), "yarn -i") 22 | } 23 | 24 | func RunTxHashScript(txbody, argTypes *string, chainId uint) (string, error) { 25 | cmd := fmt.Sprintf("yarn txhash '%s' '%s' '%d'", *txbody, *argTypes, chainId) 26 | stats := common.MustRunBashCommand(CurrentCallerDir(), cmd) 27 | if len(stats) < 2 { 28 | return "", fmt.Errorf("CalcTxHashByTSScirpt ts output error") 29 | } 30 | if !strings.HasPrefix(stats[len(stats)-1], "Done") { 31 | return "", fmt.Errorf(stats[len(stats)-1]) 32 | } 33 | return stats[len(stats)-2], nil 34 | } 35 | -------------------------------------------------------------------------------- /params/config-sign-with-privatekey-example.toml: -------------------------------------------------------------------------------- 1 | # router swap identifier, must have prefix 'routerswap' 2 | Identifier = "routerswap-test" 3 | # router swap type (eg. erc20swap, nftswap, anycallswap) 4 | SwapType = "erc20swap" 5 | # default subtype is empty. anycall has subtype of 'curve' 6 | SwapSubType = "" 7 | 8 | # modgodb database connection config 9 | [Server.MongoDB] 10 | DBURLs = [""] 11 | DBName = "" 12 | UserName = "" 13 | Password = "" 14 | 15 | # bridge API service 16 | [Server.APIServer] 17 | # listen port 18 | Port = 11556 19 | 20 | # OnChain config 21 | [OnChain] 22 | APIAddress = [""] 23 | Contract = "" 24 | 25 | # Gateways config. key is chainID 26 | [Gateways] 27 | 1660545256757 = [""] 28 | 4 = [""] 29 | 30 | # MPC config 31 | [MPC] 32 | # use private key instead (use for testing) 33 | SignWithPrivateKey = true 34 | 35 | # set signer's private key, key is chain ID (use for testing) 36 | [MPC.SignerPrivateKeys] 37 | 1660545256757 = "" 38 | 4 = "" 39 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/crypto_hash.go: -------------------------------------------------------------------------------- 1 | package tweetnacl 2 | 3 | /* 4 | #include "tweetnacl.h" 5 | */ 6 | import "C" 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // The number of bytes returned by CryptHash. 13 | const HASH_BYTES int = 64 14 | 15 | // The size of the state byte array for crypto_hashblocks. 16 | const HASHBLOCKS_STATEBYTES int = 64 17 | 18 | // The block size for the message for crypto_hashblocks. 19 | const HASHBLOCKS_BLOCKBYTES int = 128 20 | 21 | // Wrapper function for crypto_hash. 22 | // 23 | // Calculates a SHA-512 hash of the message. 24 | // 25 | // Ref. http://nacl.cr.yp.to/hash.html 26 | func CryptoHash(message []byte) ([]byte, error) { 27 | hash := make([]byte, HASH_BYTES) 28 | N := (C.ulonglong)(len(message)) 29 | 30 | rc := C.crypto_hash(makePtr(hash), 31 | makePtr(message), 32 | N) 33 | 34 | if rc == 0 { 35 | return hash, nil 36 | } 37 | 38 | return nil, fmt.Errorf("Error calculating SHA-512 hash (error code %v)", rc) 39 | } 40 | -------------------------------------------------------------------------------- /tokens/iota/utils.go: -------------------------------------------------------------------------------- 1 | package iota 2 | 3 | import ( 4 | "encoding/hex" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/log" 7 | iotago "github.com/iotaledger/iota.go/v2" 8 | ) 9 | 10 | func ConvertMessageID(txHash string) ([32]byte, error) { 11 | var msgID [32]byte 12 | if messageID, err := hex.DecodeString(txHash); err != nil { 13 | log.Warn("decode message id error", "err", err) 14 | return msgID, err 15 | } else { 16 | copy(msgID[:], messageID) 17 | return msgID, nil 18 | } 19 | } 20 | 21 | func ConvertStringToAddress(edAddr string) *iotago.Ed25519Address { 22 | if eddr, err := iotago.ParseEd25519AddressFromHexString(edAddr); err == nil { 23 | return eddr 24 | } 25 | return nil 26 | } 27 | 28 | func ConvertPubKeyToAddr(addrPubKey string) *iotago.Ed25519Address { 29 | if publicKey, err := hex.DecodeString(addrPubKey); err != nil { 30 | return nil 31 | } else { 32 | eddr := iotago.AddressFromEd25519PubKey(publicKey) 33 | return &eddr 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/TODO.md: -------------------------------------------------------------------------------- 1 | #TODO 2 | 3 | ##Data 4 | * Write good tests for metadata interpretation 5 | * Use Freeform type for _some_ memos and Previous/New/Final fields 6 | * Implement canonical signatures 7 | * Consider adding SuppressionId, NodeId, SigningHash and Hash to hashable interface and make the encoder do all four in one pass. Raw is the full encoded value with every field included. 8 | 9 | ##Peers 10 | * Implement all handlers 11 | 12 | ##Ledger 13 | * Allow subscribing to incoming Proposals/Validations/Transactions for use in listener 14 | 15 | 16 | ##Terminal 17 | 18 | ##Websockets 19 | * Add missing commands 20 | * Make connection resilient via reconnection strategy (r.ripple.com?) 21 | * Allow connection to multiple endpoints? 22 | 23 | ##Tools 24 | 25 | ###tx 26 | * Implement OfferCreate, OfferCancel, AccountSet and TrustSet commands 27 | * Use websockets to optionally acquire correct sequence number for account derived from seed 28 | * Add memo support 29 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/signing.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import "github.com/anyswap/CrossChain-Router/v3/tokens/ripple/rubblelabs/ripple/crypto" 4 | 5 | func Sign(s Signer, key crypto.Key, sequence *uint32) error { 6 | s.InitialiseForSigning() 7 | copy(s.GetPublicKey().Bytes(), key.Public(sequence)) 8 | hash, msg, err := SigningHash(s) 9 | if err != nil { 10 | return err 11 | } 12 | sig, err := crypto.Sign(key.Private(sequence), hash.Bytes(), append(s.SigningPrefix().Bytes(), msg...)) 13 | if err != nil { 14 | return err 15 | } 16 | *s.GetSignature() = VariableLength(sig) 17 | hash, _, err = Raw(s) 18 | if err != nil { 19 | return err 20 | } 21 | copy(s.GetHash().Bytes(), hash.Bytes()) 22 | return nil 23 | } 24 | 25 | func CheckSignature(s Signer) (bool, error) { 26 | hash, msg, err := SigningHash(s) 27 | if err != nil { 28 | return false, err 29 | } 30 | return crypto.Verify(s.GetPublicKey().Bytes(), hash.Bytes(), msg, s.GetSignature().Bytes()) 31 | } 32 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/crypto/util.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "crypto/sha256" 5 | "crypto/sha512" 6 | 7 | "golang.org/x/crypto/ripemd160" 8 | ) 9 | 10 | // Write operations in a hash.Hash never return an error 11 | 12 | // Returns first 32 bytes of a SHA512 of the input bytes 13 | func Sha512Half(b []byte) []byte { 14 | hasher := sha512.New() 15 | hasher.Write(b) 16 | return hasher.Sum(nil)[:32] 17 | } 18 | 19 | // Returns first 16 bytes of a SHA512 of the input bytes 20 | func Sha512Quarter(b []byte) []byte { 21 | hasher := sha512.New() 22 | hasher.Write(b) 23 | return hasher.Sum(nil)[:16] 24 | } 25 | 26 | func DoubleSha256(b []byte) []byte { 27 | hasher := sha256.New() 28 | hasher.Write(b) 29 | sha := hasher.Sum(nil) 30 | hasher.Reset() 31 | hasher.Write(sha) 32 | return hasher.Sum(nil) 33 | } 34 | 35 | func Sha256RipeMD160(b []byte) []byte { 36 | ripe := ripemd160.New() 37 | sha := sha256.New() 38 | sha.Write(b) 39 | ripe.Write(sha.Sum(nil)) 40 | return ripe.Sum(nil) 41 | } 42 | -------------------------------------------------------------------------------- /tokens/near/tools/publicKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "os" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | "github.com/anyswap/CrossChain-Router/v3/tokens/near" 9 | ) 10 | 11 | var ( 12 | paramPubKey string 13 | ) 14 | 15 | func initFlags() { 16 | flag.StringVar(¶mPubKey, "p", "", "public key hex string") 17 | 18 | flag.Parse() 19 | } 20 | 21 | func main() { 22 | log.SetLogger(6, false, true) 23 | 24 | initFlags() 25 | 26 | pubkeyHex := paramPubKey 27 | if pubkeyHex == "" && len(os.Args) > 1 { 28 | pubkeyHex = os.Args[1] 29 | } 30 | if pubkeyHex == "" { 31 | log.Fatal("miss public key argument") 32 | } 33 | 34 | nearPubKey, err := near.PublicKeyFromHexString(pubkeyHex) 35 | if err != nil { 36 | log.Fatal("convert public key to address failed", "err", err) 37 | } 38 | 39 | log.Info("convert public key to address success") 40 | log.Printf("nearAddress is %v", nearPubKey.Address()) 41 | log.Printf("nearPublicKey is %v", nearPubKey.String()) 42 | } 43 | -------------------------------------------------------------------------------- /worker/worker.go: -------------------------------------------------------------------------------- 1 | package worker 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/router/bridge" 7 | ) 8 | 9 | const interval = 10 * time.Millisecond 10 | 11 | // StartRouterSwapWork start router swap job 12 | func StartRouterSwapWork(isServer bool) { 13 | logWorker("worker", "start router swap worker") 14 | 15 | bridge.InitRouterBridges(isServer) 16 | bridge.StartReloadRouterConfigTask() 17 | 18 | if !isServer { 19 | go StartAcceptSignJob() 20 | time.Sleep(interval) 21 | StartReportStatJob() 22 | return 23 | } 24 | 25 | StartSwapJob() 26 | time.Sleep(interval) 27 | 28 | StartVerifyJob() 29 | time.Sleep(interval) 30 | 31 | StartStableJob() 32 | time.Sleep(interval) 33 | 34 | StartReplaceJob() 35 | time.Sleep(interval) 36 | 37 | StartPassBigValueJob() 38 | time.Sleep(interval) 39 | 40 | //StartAggregateJob() 41 | //time.Sleep(interval) 42 | 43 | StartCheckFailedSwapJob() 44 | time.Sleep(interval) 45 | 46 | StartReswapJob() 47 | time.Sleep(interval) 48 | } 49 | -------------------------------------------------------------------------------- /tokens/flow/transaction/Registry.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | import %s from %s 3 | 4 | transaction() { 5 | let vaultStoragePath: StoragePath 6 | let vaultPublicPath:PublicPath 7 | let vaultBalancePublicPath:PublicPath 8 | prepare(acct: AuthAccount) { 9 | self.vaultStoragePath= %s 10 | self.vaultPublicPath= %s 11 | self.vaultBalancePublicPath= %s 12 | 13 | let tempVault<- %s.createEmptyVault() 14 | acct.save<@%s.Vault>(<-tempVault, to: self.vaultStoragePath) 15 | 16 | acct.link<&{FungibleToken.Receiver}>( 17 | self.vaultPublicPath, 18 | target: self.vaultStoragePath 19 | ) 20 | 21 | // Create a public capability to the stored Vault that only exposes 22 | // the `balance` field through the `Balance` interface 23 | // 24 | acct.link<&%s.Vault{FungibleToken.Balance}>( 25 | self.vaultBalancePublicPath, 26 | target: self.vaultStoragePath 27 | ) 28 | 29 | } 30 | } -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/interface.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | type Hashable interface { 8 | GetType() string 9 | Prefix() HashPrefix 10 | GetHash() *Hash256 11 | } 12 | 13 | type Signer interface { 14 | Hashable 15 | InitialiseForSigning() 16 | SigningPrefix() HashPrefix 17 | GetPublicKey() *PublicKey 18 | GetSignature() *VariableLength 19 | } 20 | 21 | type Router interface { 22 | Hashable 23 | SuppressionId() Hash256 24 | } 25 | 26 | type Storer interface { 27 | Hashable 28 | Ledger() uint32 29 | NodeType() NodeType 30 | NodeId() *Hash256 31 | } 32 | 33 | type LedgerEntry interface { 34 | Storer 35 | GetLedgerEntryType() LedgerEntryType 36 | GetLedgerIndex() *Hash256 37 | GetPreviousTxnId() *Hash256 38 | Affects(Account) bool 39 | } 40 | 41 | type Transaction interface { 42 | Signer 43 | GetTransactionType() TransactionType 44 | GetBase() *TxBase 45 | PathSet() PathSet 46 | } 47 | 48 | type Wire interface { 49 | Unmarshal(Reader) error 50 | Marshal(io.Writer) error 51 | } 52 | -------------------------------------------------------------------------------- /tokens/cosmos/tools/getStubChainID/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/cosmos" 10 | ) 11 | 12 | var ( 13 | paramChainName string 14 | paramNetwork string 15 | ) 16 | 17 | func initFlags() { 18 | flag.StringVar(¶mChainName, "n", "", "chainName, eg. cosmoshub, osmosis, coreum, sei, etc.") 19 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, etc.") 20 | 21 | flag.Parse() 22 | } 23 | 24 | func main() { 25 | initFlags() 26 | 27 | if !cosmos.IsSupportedCosmosSubChain(paramChainName) { 28 | log.Fatalf("unknown chain name %v", paramChainName) 29 | } 30 | 31 | network := paramNetwork 32 | if network == "" && len(os.Args) > 1 { 33 | network = os.Args[1] 34 | } 35 | if network == "" { 36 | log.Fatal("miss network argument") 37 | } 38 | 39 | chainID := cosmos.GetStubChainID(paramChainName, network) 40 | fmt.Printf("%v %v: %v\n", paramChainName, network, chainID) 41 | } 42 | -------------------------------------------------------------------------------- /cmd/utils/versioncmd.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "runtime" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/params" 9 | "github.com/urfave/cli/v2" 10 | ) 11 | 12 | var ( 13 | // VersionCommand version subcommand 14 | VersionCommand = &cli.Command{ 15 | Action: version, 16 | Name: "version", 17 | Usage: "Print version numbers", 18 | ArgsUsage: " ", 19 | Description: ` 20 | The output of this command is supposed to be machine-readable. 21 | `, 22 | } 23 | ) 24 | 25 | func version(ctx *cli.Context) error { 26 | fmt.Println(clientIdentifier) 27 | fmt.Println("Version:", params.VersionWithMeta) 28 | if gitCommit != "" { 29 | fmt.Println("Git Commit:", gitCommit) 30 | } 31 | if gitDate != "" { 32 | fmt.Println("Git Commit Date:", gitDate) 33 | } 34 | fmt.Println("Architecture:", runtime.GOARCH) 35 | fmt.Println("Go Version:", runtime.Version()) 36 | fmt.Println("Operating System:", runtime.GOOS) 37 | fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) 38 | fmt.Printf("GOROOT=%s\n", runtime.GOROOT()) 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /cmd/utils/licensecmd.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/urfave/cli/v2" 7 | ) 8 | 9 | var ( 10 | // LicenseCommand license cubcommonad 11 | LicenseCommand = &cli.Command{ 12 | Action: license, 13 | Name: "license", 14 | Usage: "Display license information", 15 | ArgsUsage: " ", 16 | } 17 | ) 18 | 19 | func license(_ *cli.Context) error { 20 | fmt.Println(`CrossChain-Router is free software: you can redistribute it and/or modify 21 | it under the terms of the GNU General Public License as published by 22 | the Free Software Foundation, either version 3 of the License, or 23 | (at your option) any later version. 24 | 25 | CrossChain-Router is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU General Public License for more details. 29 | 30 | You should have received a copy of the GNU General Public License 31 | along with anyswap. If not, see .`) 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /tokens/near/sendtx.go: -------------------------------------------------------------------------------- 1 | package near 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/log" 5 | "github.com/anyswap/CrossChain-Router/v3/tokens" 6 | "github.com/near/borsh-go" 7 | ) 8 | 9 | // SendTransaction send signed tx 10 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 11 | signTx := signedTx.(*SignedTransaction) 12 | buf, err := borsh.Serialize(*signTx) 13 | if err != nil { 14 | return "", err 15 | } 16 | txHash, err = b.BroadcastTxCommit(buf) 17 | if err != nil { 18 | return "", err 19 | } 20 | return txHash, nil 21 | } 22 | 23 | // BroadcastTxCommit broadcast tx 24 | func (b *Bridge) BroadcastTxCommit(signedTx []byte) (result string, err error) { 25 | urls := b.GatewayConfig.AllGatewayURLs 26 | var success bool 27 | for _, url := range urls { 28 | result, err = BroadcastTxCommit(url, signedTx) 29 | if err == nil { 30 | success = true 31 | } else { 32 | log.Error("BroadcastTxCommit", "err", err) 33 | } 34 | } 35 | if success { 36 | return result, nil 37 | } 38 | return "", tokens.ErrBroadcastTx 39 | } 40 | -------------------------------------------------------------------------------- /tokens/cosmos/sendtx.go: -------------------------------------------------------------------------------- 1 | package cosmos 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/tokens" 9 | ) 10 | 11 | // SendTransaction send signed tx 12 | func (b *Bridge) SendTransaction(signedTx interface{}) (string, error) { 13 | if txBytes, ok := signedTx.([]byte); !ok { 14 | return "", errors.New("wrong signed transaction type") 15 | } else { 16 | req := &BroadcastTxRequest{ 17 | TxBytes: string(txBytes), 18 | Mode: "BROADCAST_MODE_SYNC", 19 | } 20 | if txRes, err := b.BroadcastTx(req); err != nil { 21 | return "", err 22 | } else { 23 | if txRes == "" { 24 | return "", tokens.ErrBroadcastTx 25 | } 26 | var txResponse *BroadcastTxResponse 27 | if err := json.Unmarshal([]byte(txRes), &txResponse); err != nil { 28 | return "", err 29 | } 30 | if txResponse.TxResponse.Code != 0 && txResponse.TxResponse.Code != 19 { 31 | return "", fmt.Errorf("SendTransaction error, code: %v", txResponse.TxResponse.Code) 32 | } 33 | return txResponse.TxResponse.TxHash, nil 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | push: 4 | pull_request: 5 | jobs: 6 | golangci: 7 | name: lint 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v3 12 | 13 | - name: Set up Go 14 | uses: actions/setup-go@v3 15 | with: 16 | go-version: 1.18 17 | 18 | - name: golangci-lint 19 | uses: golangci/golangci-lint-action@v3 20 | with: 21 | # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. 22 | version: v1.48 23 | 24 | # Optional: working directory, useful for monorepos 25 | # working-directory: somedir 26 | 27 | # Optional: golangci-lint command line arguments. 28 | # args: --issues-exit-code=0 29 | args: --timeout=10m --skip-dirs tokens/ripple/rubblelabs 30 | 31 | # Optional: show only new issues if it's a pull request. The default value is `false`. 32 | # only-new-issues: true 33 | -------------------------------------------------------------------------------- /tokens/eth/callapi/arbitrum.go: -------------------------------------------------------------------------------- 1 | package callapi 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/common" 5 | "github.com/anyswap/CrossChain-Router/v3/tokens/eth/abicoder" 6 | "github.com/anyswap/CrossChain-Router/v3/types" 7 | ) 8 | 9 | // ------------------------ arbitrum override apis ----------------------------- 10 | 11 | const arbQueryConfirmationsContract = "0x00000000000000000000000000000000000000C8" 12 | 13 | // function getL1Confirmations(bytes32 blockHash) external view returns (uint64 confirmations) 14 | var getL1ConfirmationsFuncHash = common.FromHex("0xe5ca238c") 15 | 16 | // ArbGetBlockConfirmations get block confirmations 17 | // call getL1Confirmations to 0x00000000000000000000000000000000000000C8 18 | func ArbGetBlockConfirmations(b EvmBridge, receipt *types.RPCTxReceipt) (uint64, error) { 19 | res, err := b.CallContract( 20 | arbQueryConfirmationsContract, 21 | abicoder.PackDataWithFuncHash(getL1ConfirmationsFuncHash, *receipt.BlockHash), 22 | "latest", 23 | ) 24 | if err != nil { 25 | return 0, err 26 | } 27 | return common.GetBigInt(common.FromHex(res), 0, 32).Uint64(), nil 28 | } 29 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/validation.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | type Validation struct { 4 | Hash Hash256 5 | Flags uint32 6 | LedgerHash Hash256 7 | LedgerSequence uint32 8 | Amendments Vector256 9 | SigningTime RippleTime 10 | SigningPubKey PublicKey 11 | Signature VariableLength 12 | CloseTime *uint32 13 | LoadFee *uint32 14 | BaseFee *uint64 15 | ReserveBase *uint32 16 | ReserveIncrement *uint32 17 | } 18 | 19 | func (v Validation) GetType() string { return "Validation" } 20 | func (v Validation) GetPublicKey() *PublicKey { return &v.SigningPubKey } 21 | func (v Validation) GetSignature() *VariableLength { return &v.Signature } 22 | func (v Validation) Prefix() HashPrefix { return HP_VALIDATION } 23 | func (v Validation) SigningPrefix() HashPrefix { return HP_VALIDATION } 24 | func (v Validation) SuppressionId() (Hash256, error) { return NodeId(&v) } 25 | func (v Validation) GetHash() *Hash256 { return &v.Hash } 26 | func (v Validation) InitialiseForSigning() {} 27 | -------------------------------------------------------------------------------- /mongodb/errors.go: -------------------------------------------------------------------------------- 1 | package mongodb 2 | 3 | import ( 4 | "errors" 5 | 6 | rpcjson "github.com/gorilla/rpc/v2/json2" 7 | "go.mongodb.org/mongo-driver/mongo" 8 | ) 9 | 10 | func newError(ec rpcjson.ErrorCode, message string) error { 11 | return &rpcjson.Error{ 12 | Code: ec, 13 | Message: message, 14 | } 15 | } 16 | 17 | func mgoError(err error) error { 18 | if err != nil { 19 | if errors.Is(err, mongo.ErrNoDocuments) { 20 | return ErrItemNotFound 21 | } 22 | if mongo.IsDuplicateKeyError(err) { 23 | return ErrItemIsDup 24 | } 25 | return newError(-32001, "mgoError: "+err.Error()) 26 | } 27 | return nil 28 | } 29 | 30 | // mongodb special errors 31 | var ( 32 | ErrItemNotFound = newError(-32002, "mgoError: Item not found") 33 | ErrItemIsDup = newError(-32003, "mgoError: Item is duplicate") 34 | ErrSwapNotFound = newError(-32011, "mgoError: Swap is not found") 35 | ErrWrongKey = newError(-32012, "mgoError: Wrong key") 36 | ErrForbidUpdateNonce = newError(-32013, "mgoError: Forbid update swap nonce") 37 | ErrForbidUpdateSwapTx = newError(-32014, "mgoError: Forbid update swap tx") 38 | ) 39 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/util.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "crypto/sha512" 5 | ) 6 | 7 | const hextable = "0123456789ABCDEF" 8 | 9 | //faster than fmt and need upper case! 10 | func b2h(h []byte) []byte { 11 | b := make([]byte, len(h)*2) 12 | for i, v := range h { 13 | b[i*2] = hextable[v>>4] 14 | b[i*2+1] = hextable[v&0x0f] 15 | } 16 | return b 17 | } 18 | 19 | func min(a, b uint32) uint32 { 20 | if a < b { 21 | return a 22 | } 23 | return b 24 | } 25 | 26 | func max(a, b uint32) uint32 { 27 | if a > b { 28 | return a 29 | } 30 | return b 31 | } 32 | 33 | func min64(a, b uint64) uint64 { 34 | if a < b { 35 | return a 36 | } 37 | return b 38 | } 39 | 40 | func max64(a, b uint64) uint64 { 41 | if a > b { 42 | return a 43 | } 44 | return b 45 | } 46 | 47 | func abs(a int64) uint64 { 48 | if a < 0 { 49 | return uint64(-a) 50 | } 51 | return uint64(a) 52 | } 53 | 54 | func hashValues(values []interface{}) (Hash256, error) { 55 | var hash Hash256 56 | hasher := sha512.New() 57 | for _, v := range values { 58 | if err := write(hasher, v); err != nil { 59 | return hash, err 60 | } 61 | } 62 | copy(hash[:], hasher.Sum(nil)) 63 | return hash, nil 64 | } 65 | -------------------------------------------------------------------------------- /tools/loadkeystore.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "strings" 9 | 10 | "github.com/anyswap/CrossChain-Router/v3/tools/keystore" 11 | ) 12 | 13 | var errUnsafeFilePermissions = errors.New("unsafe file permissions, want 0400") 14 | 15 | // SafeReadFile check permissions is '0400' and read file 16 | func SafeReadFile(file string) ([]byte, error) { 17 | fi, err := os.Stat(file) 18 | if err != nil { 19 | return nil, err 20 | } 21 | if fi.Mode() != 0400 { 22 | return nil, errUnsafeFilePermissions 23 | } 24 | return ioutil.ReadFile(file) 25 | } 26 | 27 | // LoadKeyStore load keystore from keyfile and passfile 28 | func LoadKeyStore(keyfile, passfile string) (*keystore.Key, error) { 29 | keyjson, err := SafeReadFile(keyfile) 30 | if err != nil { 31 | return nil, fmt.Errorf("read keystore fail %w", err) 32 | } 33 | passdata, err := SafeReadFile(passfile) 34 | if err != nil { 35 | return nil, fmt.Errorf("read password fail %w", err) 36 | } 37 | passwd := strings.TrimSpace(string(passdata)) 38 | key, err := keystore.DecryptKey(keyjson, passwd) 39 | if err != nil { 40 | return nil, fmt.Errorf("decrypt key fail %w", err) 41 | } 42 | return key, nil 43 | } 44 | -------------------------------------------------------------------------------- /tokens/btc/sendtx.go: -------------------------------------------------------------------------------- 1 | package btc 2 | 3 | import ( 4 | "bytes" 5 | "encoding/hex" 6 | "errors" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/tokens" 9 | "github.com/btcsuite/btcwallet/wallet/txauthor" 10 | ) 11 | 12 | // SendTransaction send signed tx 13 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 14 | authoredTx, ok := signedTx.(*txauthor.AuthoredTx) 15 | if !ok { 16 | return "", tokens.ErrWrongRawTx 17 | } 18 | 19 | tx := authoredTx.Tx 20 | if tx == nil { 21 | return "", tokens.ErrWrongRawTx 22 | } 23 | 24 | buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize())) 25 | err = tx.Serialize(buf) 26 | if err != nil { 27 | return "", err 28 | } 29 | txHex := hex.EncodeToString(buf.Bytes()) 30 | 31 | return b.BroadcastTxCommit(txHex) 32 | } 33 | 34 | // PostTransaction impl 35 | func (b *Bridge) BroadcastTxCommit(txHex string) (txHash string, err error) { 36 | urls := b.GatewayConfig.AllGatewayURLs 37 | var success bool 38 | for _, url := range urls { 39 | txHash, err = PostTransaction(url, txHex) 40 | if err == nil { 41 | success = true 42 | } 43 | } 44 | if success { 45 | return txHash, nil 46 | } 47 | return "", errors.New("PostTransaction error") 48 | } 49 | -------------------------------------------------------------------------------- /tokens/flow/ReadMe_front_zh.md: -------------------------------------------------------------------------------- 1 | ## flow 2 | 合约仓库: https://github.com/anyswap/flow-contract 3 | 4 | ## sdk 5 | https://developers.onflow.org/tools/fcl-js 6 | 7 | ## api 8 | https://developers.onflow.org/http-api/ 9 | 10 | ## method 11 | >1)tokenInfo 12 | ```shell 13 | decimal: 6 14 | name/symbol: contractAddr 15 | ``` 16 | >2)underlying 17 | ```shell 18 | code: https://github.com/anyswap/flow-contract/blob/main/contracts/multichain/AnyExampleToken.cdc 19 | method: pub fun underlying(): String? 20 | ``` 21 | >3)native balance 22 | ```shell 23 | code: https://github.com/anyswap/flow-contract/blob/main/contracts/core/FungibleToken.cdc 24 | method: pub fun deposit(from: @Vault) 25 | ``` 26 | >4)token balance 27 | ```shell 28 | code: https://github.com/anyswap/flow-contract/blob/main/contracts/core/FungibleToken.cdc 29 | method: pub fun deposit(from: @Vault) 30 | ``` 31 | >5)totalSupply 32 | ```shell 33 | code: https://github.com/anyswap/flow-contract/blob/main/contracts/core/FungibleToken.cdc 34 | method: pub var totalSupply: UFix64 35 | ``` 36 | >6)create vault 37 | ```shell 38 | code: https://github.com/near/near-sdk-rs/blob/master/near-contract-standards/src/fungible_token/storage_impl.rs 39 | method: pub fun createEmptyVault(): @Vault 40 | ``` 41 | 42 | -------------------------------------------------------------------------------- /tokens/aptos/tools/calcTxhashTest/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/log" 5 | "github.com/anyswap/CrossChain-Router/v3/tokens/aptos" 6 | ) 7 | 8 | func main() { 9 | aptos.InstallTsModules() 10 | 11 | txbody := `{"sender":"0x06da2b6027d581ded49b2314fa43016079e0277a17060437236f8009550961d6","sequence_number":"58","max_gas_amount":"100000","gas_unit_price":"1000","expiration_timestamp_secs":"1666244737","payload":{"type":"entry_function_payload","function":"0x06da2b6027d581ded49b2314fa43016079e0277a17060437236f8009550961d6::wETH::mint","type_arguments":[],"arguments":["0x10878abd3802be00d674709b1e5554488823f5f825bce8d1efaf370e9aaac777","100000000000000000"]},"signature":{"type":"ed25519_signature","public_key":"0x11e202042f518e9bd719296fa36007017948392f6557d2796c81677620e5a4a4","signature":"0xd3934d202a9de3178e9b280fdcfd614bb9f82d2ffd0e305898f483cdf48cf67c8350451147a5a6644d590f0a18892b12af37f47de46dd5c44ed7e2183865180b"}}` 12 | 13 | argTypes := `address,uint64` 14 | 15 | chainId := uint(2) 16 | 17 | res, err := aptos.RunTxHashScript(&txbody, &argTypes, chainId) 18 | if err != nil { 19 | log.Fatal("RunTxHashScript failed", "err", err) 20 | } 21 | log.Infof("RunTxHashScript success. txHash is %v", res) 22 | } 23 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/proposal.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | type Proposal struct { 4 | Hash Hash256 5 | LedgerHash Hash256 6 | PreviousLedger Hash256 7 | Sequence uint32 8 | CloseTime RippleTime 9 | PublicKey PublicKey 10 | Signature VariableLength 11 | } 12 | 13 | func (p Proposal) GetType() string { return "Proposal" } 14 | func (p *Proposal) GetPublicKey() *PublicKey { return &p.PublicKey } 15 | func (p *Proposal) GetSignature() *VariableLength { return &p.Signature } 16 | func (p *Proposal) Prefix() HashPrefix { return HP_PROPOSAL } 17 | func (p *Proposal) SigningPrefix() HashPrefix { return HP_PROPOSAL } 18 | func (p *Proposal) GetHash() *Hash256 { return &p.Hash } 19 | func (p *Proposal) InitialiseForSigning() {} 20 | 21 | func (p Proposal) SigningValues() []interface{} { 22 | return []interface{}{ 23 | p.Sequence, 24 | p.CloseTime.Uint32(), 25 | p.PreviousLedger, 26 | p.LedgerHash, 27 | } 28 | } 29 | 30 | func (p Proposal) SuppressionId() (Hash256, error) { 31 | return hashValues([]interface{}{ 32 | p.LedgerHash, 33 | p.PreviousLedger, 34 | p.Sequence, 35 | p.CloseTime.Uint32(), 36 | p.PublicKey, 37 | p.Signature, 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /tokens/solana/types/registry.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // InstructionDecoder receives the AccountMeta FOR THAT INSTRUCTION, 8 | // and not the accounts of the *Message object. Resolve with 9 | // CompiledInstruction.ResolveInstructionAccounts(message) beforehand. 10 | type InstructionDecoder func(instructionAccounts []*AccountMeta, data []byte) (interface{}, error) 11 | 12 | // InstructionDecoderRegistry instruction decoder registry 13 | var InstructionDecoderRegistry = map[string]InstructionDecoder{} 14 | 15 | // RegisterInstructionDecoder register instruction decoder 16 | func RegisterInstructionDecoder(programID PublicKey, decoder InstructionDecoder) { 17 | p := programID.String() 18 | if _, found := InstructionDecoderRegistry[p]; found { 19 | return 20 | } 21 | 22 | InstructionDecoderRegistry[p] = decoder 23 | } 24 | 25 | // DecodeInstruction decode instruction 26 | func DecodeInstruction(programID PublicKey, accounts []*AccountMeta, data []byte) (interface{}, error) { 27 | p := programID.String() 28 | 29 | decoder, found := InstructionDecoderRegistry[p] 30 | if !found { 31 | return nil, fmt.Errorf("unknown programID, cannot find any instruction decoder %q", p) 32 | } 33 | 34 | return decoder(accounts, data) 35 | } 36 | -------------------------------------------------------------------------------- /tokens/flow/sendtx.go: -------------------------------------------------------------------------------- 1 | package flow 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/log" 5 | "github.com/anyswap/CrossChain-Router/v3/params" 6 | "github.com/anyswap/CrossChain-Router/v3/tokens" 7 | sdk "github.com/onflow/flow-go-sdk" 8 | ) 9 | 10 | // SendTransaction send signed tx 11 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 12 | tx := signedTx.(*sdk.Transaction) 13 | txHash, err = b.BroadcastTxCommit(tx) 14 | if err != nil { 15 | log.Warn("SendTransaction failed", "err", err) 16 | return "", err 17 | } 18 | log.Info("SendTransaction success", "hash", txHash) 19 | if !params.IsParallelSwapEnabled() { 20 | sender := tx.Payer 21 | nonce := tx.ProposalKey.SequenceNumber 22 | b.SetNonce(sender.Hex(), nonce+1) 23 | } 24 | return txHash, nil 25 | } 26 | 27 | func (b *Bridge) BroadcastTxCommit(signedTx *sdk.Transaction) (txHash string, err error) { 28 | urls := b.GatewayConfig.AllGatewayURLs 29 | var success bool 30 | for _, url := range urls { 31 | txHash, err = sendTransaction(url, signedTx) 32 | if err == nil { 33 | success = true 34 | } else { 35 | log.Warn("BroadcastTxCommit failed", "err", err) 36 | } 37 | } 38 | if success { 39 | return txHash, nil 40 | } 41 | return "", tokens.ErrSendTx 42 | } 43 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/reader.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | type Reader interface { 8 | io.ByteScanner 9 | io.Reader 10 | Len() int 11 | } 12 | 13 | type LimitByteReader struct { 14 | R Reader // underlying reader 15 | N int64 // max bytes remaining 16 | } 17 | 18 | func LimitedByteReader(r Reader, n int64) *LimitByteReader { 19 | return &LimitByteReader{r, n} 20 | } 21 | 22 | func (l *LimitByteReader) Len() int { 23 | return int(l.N) 24 | } 25 | 26 | func NewVariableByteReader(r Reader) (Reader, error) { 27 | if length, err := readVariableLength(r); err != nil { 28 | return nil, err 29 | } else { 30 | return LimitedByteReader(r, int64(length)), nil 31 | } 32 | } 33 | 34 | func (l *LimitByteReader) Read(p []byte) (n int, err error) { 35 | if l.N <= 0 { 36 | return 0, io.EOF 37 | } 38 | if int64(len(p)) > l.N { 39 | p = p[0:l.N] 40 | } 41 | n, err = l.R.Read(p) 42 | l.N -= int64(n) 43 | return 44 | } 45 | 46 | func (l *LimitByteReader) ReadByte() (c byte, err error) { 47 | if l.N <= 0 { 48 | return 0, io.EOF 49 | } 50 | l.N-- 51 | return l.R.ReadByte() 52 | } 53 | 54 | func (l *LimitByteReader) UnreadByte() error { 55 | if err := l.UnreadByte(); err != nil { 56 | return err 57 | } 58 | l.N++ 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /tokens/stellar/README_frontend.md: -------------------------------------------------------------------------------- 1 | # stellar frontend 2 | 3 | ## rpc 4 | 5 | https://horizon.stellar.org/ for interacting with the public network 6 | https://horizon-testnet.stellar.org/ for interacting with the testnet 7 | 8 | ## query token info 9 | 10 | see https://stellar.github.io/js-stellar-sdk/AssetsCallBuilder.html 11 | 12 | example 13 | https://horizon-testnet.stellar.org/assets?asset_code=0&asset_issuer=GDQ4TZ2JQ66S4GKCINHRBYBDO5D4U7FCNALFTCY45O5RUWLPYBC3BJ2N 14 | 15 | ## query native balance 16 | 17 | see https://stellar.github.io/js-stellar-sdk/AccountCallBuilder.html 18 | refer the props `balances` 19 | 20 | 21 | example 22 | https://horizon-testnet.stellar.org/accounts/GA7EDFQK7ZOSVEVNCGCMLJVC5SDT5PYFYEKUI5IFNHJUA5PQ6OJMP5GC 23 | 24 | ## token balanceOf 25 | 26 | the same as `query native balance` 27 | 28 | ## query token total supply 29 | 30 | see https://stellar.github.io/js-stellar-sdk/AssetsCallBuilder.html 31 | refer the props `balances.authorized` 32 | 33 | 34 | example 35 | https://horizon-testnet.stellar.org/assets?asset_code=Ooxx&asset_issuer=GCHH22AXHDDXET47Q3YKSANZ74GAAWEIMECQ3ZNFVM3SJY2LGYYPFLUH 36 | 37 | ## build tx memo 38 | 39 | see https://github.com/anyswap/CrossChain-Router/blob/feature/stellar/tokens/stellar/README.md#router-mechanism 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/crypto/const.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | type HashVersion byte 4 | 5 | const ( 6 | ACCOUNT_ZERO = "rrrrrrrrrrrrrrrrrrrrrhoLvTp" 7 | ACCOUNT_ONE = "rrrrrrrrrrrrrrrrrrrrBZbvji" 8 | NaN = "rrrrrrrrrrrrrrrrrrrn5RM1rHd" 9 | ROOT = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" 10 | ) 11 | 12 | const ( 13 | ALPHABET = "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz" 14 | 15 | RIPPLE_ACCOUNT_ID HashVersion = 0 16 | RIPPLE_NODE_PUBLIC HashVersion = 28 17 | RIPPLE_NODE_PRIVATE HashVersion = 32 18 | RIPPLE_FAMILY_SEED HashVersion = 33 19 | RIPPLE_ACCOUNT_PRIVATE HashVersion = 34 20 | RIPPLE_ACCOUNT_PUBLIC HashVersion = 35 21 | ) 22 | 23 | var hashTypes = [...]struct { 24 | Description string 25 | Prefix byte 26 | Payload int 27 | MaximumCharacters int 28 | }{ 29 | RIPPLE_ACCOUNT_ID: {"Short name for sending funds to an account.", 'r', 20, 35}, 30 | RIPPLE_NODE_PUBLIC: {"Validation public key for node.", 'n', 33, 53}, 31 | RIPPLE_NODE_PRIVATE: {"Validation private key for node.", 'p', 32, 52}, 32 | RIPPLE_FAMILY_SEED: {"Family seed.", 's', 16, 29}, 33 | RIPPLE_ACCOUNT_PRIVATE: {"Account private key.", 'p', 32, 52}, 34 | RIPPLE_ACCOUNT_PUBLIC: {"Account public key.", 'a', 33, 53}, 35 | } 36 | -------------------------------------------------------------------------------- /params/version.go: -------------------------------------------------------------------------------- 1 | // Package params provides common version info and config items. 2 | package params 3 | 4 | import ( 5 | "fmt" 6 | ) 7 | 8 | // version parts 9 | const ( 10 | VersionMajor = 3 // Major version component of the current release 11 | VersionMinor = 6 // Minor version component of the current release 12 | VersionPatch = 2 // Patch version component of the current release 13 | VersionMeta = "" // Version metadata to append to the version string 14 | ) 15 | 16 | // Version holds the textual version string. 17 | var Version = func() string { 18 | return fmt.Sprintf("%d.%d.%d", VersionMajor, VersionMinor, VersionPatch) 19 | }() 20 | 21 | // VersionWithMeta holds the textual version string including the metadata. 22 | var VersionWithMeta = func() string { 23 | v := Version 24 | if VersionMeta != "" { 25 | v += "-" + VersionMeta 26 | } 27 | return v 28 | }() 29 | 30 | // VersionWithCommit add git commit and data to version. 31 | func VersionWithCommit(gitCommit, gitDate string) string { 32 | vsn := Version 33 | if VersionMeta != "" { 34 | vsn += "-" + VersionMeta 35 | } 36 | if len(gitCommit) >= 8 { 37 | vsn += "-" + gitCommit[:8] 38 | } 39 | if (VersionMeta != "stable") && (gitDate != "") { 40 | vsn += "-" + gitDate 41 | } 42 | VersionWithMeta = vsn // update if more concrete 43 | return vsn 44 | } 45 | -------------------------------------------------------------------------------- /tokens/rpccall.go: -------------------------------------------------------------------------------- 1 | package tokens 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/common" 7 | "github.com/anyswap/CrossChain-Router/v3/rpc/client" 8 | ) 9 | 10 | // WrapRPCQueryError wrap rpc error 11 | func WrapRPCQueryError(err error, method string, params ...interface{}) error { 12 | if err == nil { 13 | return fmt.Errorf("call '%s %v' failed, err='%w'", method, params, ErrNotFound) 14 | } 15 | return fmt.Errorf("%w: call '%s %v' failed, err='%v'", ErrRPCQueryError, method, params, common.FirstN(err.Error(), 166)) 16 | } 17 | 18 | // RPCCall common RPC calling 19 | func RPCCall(result interface{}, urls []string, method string, params ...interface{}) (err error) { 20 | for _, url := range urls { 21 | err = client.RPCPost(&result, url, method, params...) 22 | if err == nil { 23 | return nil 24 | } 25 | } 26 | return WrapRPCQueryError(err, method, params...) 27 | } 28 | 29 | // RPCCallWithTimeout common RPC calling with specified timeout 30 | func RPCCallWithTimeout(timeout int, result interface{}, urls []string, method string, params ...interface{}) (err error) { 31 | for _, url := range urls { 32 | err = client.RPCPostWithTimeout(timeout, &result, url, method, params...) 33 | if err == nil { 34 | return nil 35 | } 36 | } 37 | return WrapRPCQueryError(err, method, params...) 38 | } 39 | -------------------------------------------------------------------------------- /tokens/iota/type.go: -------------------------------------------------------------------------------- 1 | package iota 2 | 3 | import iotago "github.com/iotaledger/iota.go/v2" 4 | 5 | type Address struct { 6 | Type uint64 `json:"type"` 7 | Address string `json:"address"` 8 | } 9 | 10 | type RawType struct { 11 | Type uint64 `json:"type"` 12 | Address Address `json:"address"` 13 | Amount uint64 `json:"amount"` 14 | } 15 | 16 | type MessagePayload struct { 17 | Type uint64 `json:"type"` 18 | Essence Essence `json:"essence"` 19 | } 20 | 21 | type Essence struct { 22 | Type uint64 `json:"type"` 23 | Inputs []Input `json:"inputs"` 24 | Outputs []Output `json:"outputs"` 25 | Payload Payload `json:"payload"` 26 | } 27 | 28 | type Input struct { 29 | Type uint64 `json:"type"` 30 | TransactionId string `json:"transactionId"` 31 | TransactionOutputIndex uint64 `json:"transactionOutputIndex"` 32 | } 33 | 34 | type Output struct { 35 | Type uint64 `json:"type"` 36 | Address Address `json:"address"` 37 | Amount uint64 `json:"amount"` 38 | } 39 | 40 | type Payload struct { 41 | Type uint64 `json:"type"` 42 | Index string `json:"index"` 43 | Data string `json:"data"` 44 | } 45 | 46 | type MessageBuilder struct { 47 | TransactionBuilder *iotago.TransactionBuilder `json:"transactionBuilder"` 48 | Essence *iotago.TransactionEssence `json:"essence"` 49 | } 50 | -------------------------------------------------------------------------------- /tokens/stellar/sendtx.go: -------------------------------------------------------------------------------- 1 | package stellar 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | "github.com/anyswap/CrossChain-Router/v3/tokens" 9 | hProtocol "github.com/stellar/go/protocols/horizon" 10 | "github.com/stellar/go/txnbuild" 11 | ) 12 | 13 | // SendTransaction send signed tx 14 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 15 | tx, ok := signedTx.(*txnbuild.Transaction) 16 | if !ok { 17 | return "", tokens.ErrWrongRawTx 18 | } 19 | var success bool 20 | var resp hProtocol.Transaction 21 | for i := 0; i < rpcRetryTimes; i++ { 22 | // try send to all remotes 23 | for _, r := range b.Remotes { 24 | resp, err = r.SubmitTransaction(tx) 25 | if err != nil { 26 | log.Warn("Try sending transaction failed", "error", err) 27 | continue 28 | } 29 | if !resp.Successful { 30 | log.Warn("send tx with error result", "result", resp.Successful, "message") 31 | err = fmt.Errorf("swapin failed txhash:%s result %v", txHash, resp.Successful) 32 | success = false 33 | } else { 34 | txHash = resp.Hash 35 | success = true 36 | } 37 | break 38 | } 39 | if success { 40 | break 41 | } 42 | time.Sleep(rpcRetryInterval) 43 | } 44 | if success { 45 | return txHash, nil 46 | } 47 | return "", err 48 | } 49 | -------------------------------------------------------------------------------- /tokens/flow/transaction/SwapIn.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | import Router from %s 3 | 4 | transaction(tx:String,token:String,receiver:Address,fromChainId:UInt64,amount:UFix64,receivePaths:[String]) { 5 | let mpcRef: &Router.Mpc 6 | let mpcStoragePath: StoragePath 7 | let vaultPublicPath:PublicPath 8 | let anyVaultPublicPath:PublicPath 9 | let receiverRef:Capability<&{FungibleToken.Receiver}> 10 | let receiverAnyRef:Capability<&{FungibleToken.Receiver}> 11 | prepare(acct: AuthAccount) { 12 | self.mpcStoragePath = /storage/routerMpc 13 | self.vaultPublicPath = PublicPath(identifier: receivePaths[0])! 14 | self.anyVaultPublicPath = PublicPath(identifier: receivePaths[1])! 15 | self.mpcRef=acct.borrow<&Router.Mpc>(from:self.mpcStoragePath) 16 | ??panic("Could not borrow a reference to the crosschain") 17 | let recipient=getAccount(receiver) 18 | self.receiverRef = recipient.getCapability<&{FungibleToken.Receiver}>(self.vaultPublicPath) 19 | self.receiverAnyRef = recipient.getCapability<&{FungibleToken.Receiver}>(self.anyVaultPublicPath) 20 | } 21 | 22 | execute { 23 | self.mpcRef.swapIn(tx:tx,token:token,fromChainId:fromChainId,amount:amount,receivePaths:[self.receiverRef,self.receiverAnyRef]) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tokens/eth/routercontract.go: -------------------------------------------------------------------------------- 1 | package eth 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/common" 8 | ) 9 | 10 | var ( 11 | cachedPairsMap = make(map[string]string) // key is of format `chainid:token0:token1` (lowercase) 12 | ) 13 | 14 | func getCachedPairKey(chainID, token0, token1 string) string { 15 | return strings.ToLower(fmt.Sprintf("%v:%v:%v", chainID, token0, token1)) 16 | } 17 | 18 | // GetPairFor call "getPair(address,address)" 19 | func (b *Bridge) GetPairFor(factory, token0, token1 string) (string, error) { 20 | // first search in cache 21 | key := getCachedPairKey(b.ChainConfig.ChainID, token0, token1) 22 | cachedPairs := cachedPairsMap[key] 23 | if cachedPairs != "" { 24 | return cachedPairs, nil 25 | } 26 | 27 | faunHash := common.FromHex("0xe6a43905") 28 | data := make([]byte, 68) 29 | copy(data[:4], faunHash) 30 | copy(data[4:36], common.HexToAddress(token0).Hash().Bytes()) 31 | copy(data[36:68], common.HexToAddress(token1).Hash().Bytes()) 32 | res, err := b.EvmContractBridge.CallContract(factory, data, "latest") 33 | if err != nil { 34 | return "", err 35 | } 36 | pairs := common.BytesToAddress(common.GetData(common.FromHex(res), 0, 32)).LowerHex() 37 | cachedPairsMap[key] = pairs 38 | cachedPairsMap[getCachedPairKey(b.ChainConfig.ChainID, token1, token0)] = pairs 39 | return pairs, nil 40 | } 41 | -------------------------------------------------------------------------------- /tokens/iota/address.go: -------------------------------------------------------------------------------- 1 | package iota 2 | 3 | import ( 4 | "errors" 5 | 6 | iotago "github.com/iotaledger/iota.go/v2" 7 | ) 8 | 9 | // IsValidAddress check address 10 | func (b *Bridge) IsValidAddress(addr string) bool { 11 | return true 12 | } 13 | 14 | // PublicKeyToAddress impl 15 | func (b *Bridge) PublicKeyToAddress(pubKeyHex string) (string, error) { 16 | urls := b.GetGatewayConfig().AllGatewayURLs 17 | for _, url := range urls { 18 | nodeHTTPAPIClient := iotago.NewNodeHTTPAPIClient(url) 19 | // fetch the node's info to know the min. required PoW score 20 | if info, err := nodeHTTPAPIClient.Info(ctx); err == nil { 21 | edAddr := ConvertStringToAddress(pubKeyHex) 22 | bech32Addr := edAddr.Bech32(iotago.NetworkPrefix(info.Bech32HRP)) 23 | return bech32Addr, nil 24 | } 25 | } 26 | return "", errors.New("PublicKeyToAddress eror") 27 | } 28 | 29 | // VerifyMPCPubKey verify mpc address and public key is matching 30 | func VerifyMPCPubKey(mpcAddress, mpcPubkey string) error { 31 | edAddr := ConvertPubKeyToAddr(mpcPubkey) 32 | if edAddr.String() == mpcAddress { 33 | return nil 34 | } 35 | return errors.New("VerifyMPCPubKey eror") 36 | } 37 | 38 | func Bech32ToEdAddr(bech32 string) (*iotago.Address, error) { 39 | if _, edAddr, err := iotago.ParseBech32(bech32); err == nil { 40 | return &edAddr, nil 41 | } else { 42 | return nil, err 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tokens/btc/tools/pubKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/common" 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/btc" 10 | "github.com/btcsuite/btcutil" 11 | ) 12 | 13 | var ( 14 | paramPubKey string 15 | paramChainID string 16 | ) 17 | 18 | func initFlags() { 19 | flag.StringVar(¶mPubKey, "pubKey", "", "pubKey") 20 | flag.StringVar(¶mChainID, "chainID", "", "chainId") 21 | 22 | flag.Parse() 23 | } 24 | 25 | func main() { 26 | log.SetLogger(6, false, true) 27 | 28 | initFlags() 29 | 30 | if paramPubKey == "" { 31 | log.Fatal("miss paramPubKey argument") 32 | } 33 | 34 | pkData := common.FromHex(paramPubKey) 35 | b := btc.NewCrossChainBridge() 36 | cPkData, err := b.ToCompressedPublicKey(pkData) 37 | if err != nil { 38 | log.Fatal("ToCompressedPublicKey fails", "paramPubKey", paramPubKey) 39 | } 40 | chainID, err := common.GetBigIntFromStr(paramChainID) 41 | if err != nil { 42 | log.Fatal("GetBigIntFromStr fails", "paramChainID", paramChainID) 43 | } 44 | chainParams := b.GetChainParams(chainID) 45 | address, err := btcutil.NewAddressPubKeyHash(btcutil.Hash160(cPkData), chainParams) 46 | if err != nil { 47 | log.Fatal("NewAddressPubKeyHash fails", "paramPubKey", paramPubKey) 48 | } 49 | fmt.Printf("address: %v\n", address) 50 | } 51 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/inner.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type InnerNodeFunc func(pos int, child Hash256) error 9 | 10 | type InnerNode struct { 11 | Id Hash256 12 | Type NodeType 13 | Children [16]Hash256 14 | } 15 | 16 | type CompressedNodeEntry struct { 17 | Hash Hash256 18 | Pos uint8 19 | } 20 | 21 | func (n InnerNode) GetType() string { return nodeTypes[n.Type] } 22 | func (n InnerNode) Prefix() HashPrefix { return HP_INNER_NODE } 23 | func (n InnerNode) NodeType() NodeType { return n.Type } 24 | func (n InnerNode) Ledger() uint32 { return 0 } 25 | func (n InnerNode) GetHash() *Hash256 { return &n.Id } 26 | func (n InnerNode) NodeId() *Hash256 { return &n.Id } 27 | 28 | func (n InnerNode) Each(f InnerNodeFunc) error { 29 | for i, node := range n.Children { 30 | if !node.IsZero() { 31 | if err := f(i, node); err != nil { 32 | return err 33 | } 34 | } 35 | } 36 | return nil 37 | } 38 | 39 | func (n InnerNode) Count() int { 40 | var count int 41 | n.Each(func(i int, child Hash256) error { 42 | count++ 43 | return nil 44 | }) 45 | return count 46 | } 47 | 48 | func (n InnerNode) String() string { 49 | var s []string 50 | n.Each(func(i int, child Hash256) error { 51 | s = append(s, child.String()) 52 | return nil 53 | }) 54 | return fmt.Sprintf("%s: [%s]", n.GetType(), strings.Join(s, ",")) 55 | } 56 | -------------------------------------------------------------------------------- /tokens/flow/contracts/AnyToken.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | 3 | pub contract interface AnyToken { 4 | 5 | // pub func underlyingDeposit 6 | // pub func underlyingWithdraw 7 | pub resource interface IMinter{ 8 | pub fun mint(amount:UFix64):@FungibleToken.Vault { 9 | post { 10 | result.balance == amount: 11 | "Balance for result must equals to amount from input" 12 | } 13 | } 14 | 15 | pub fun burn(from: @FungibleToken.Vault) { 16 | pre { 17 | from.balance > 0.0: 18 | "Balance for swapOut must be more than zero" 19 | } 20 | } 21 | // withdraw 22 | } 23 | 24 | pub resource Minter:IMinter{ 25 | 26 | pub fun mint(amount: UFix64): @FungibleToken.Vault { 27 | pre { 28 | amount > 0.0: 29 | "Amount for swapIn must be more than zero" 30 | } 31 | post { 32 | result.balance == amount: 33 | "Balance for result must equals to amount from input" 34 | } 35 | } 36 | 37 | pub fun burn(from: @FungibleToken.Vault) { 38 | pre { 39 | from.balance > 0.0: 40 | "Balance for swapOut must be more than zero" 41 | } 42 | } 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /tokens/flow/key.go: -------------------------------------------------------------------------------- 1 | package flow 2 | 3 | import ( 4 | "encoding/hex" 5 | "math/big" 6 | ) 7 | 8 | const ( 9 | // PubKeyBytesLenCompressed is compressed pubkey byte length 10 | PubKeyBytesLenCompressed = 33 11 | // PubKeyBytesLenUncompressed is uncompressed pubkey byte length 12 | PubKeyBytesLenUncompressed = 65 13 | ) 14 | 15 | const ( 16 | pubkeyCompressed byte = 0x2 17 | ) 18 | 19 | // EcdsaPublic struct ripple ecdsa pubkey key 20 | type EcdsaPublic struct { 21 | pub []byte 22 | } 23 | 24 | // Private not used 25 | func (k *EcdsaPublic) Private(sequence *uint32) []byte { 26 | return nil 27 | } 28 | 29 | // Public returns pubkey bytes 30 | func (k *EcdsaPublic) Public(sequence *uint32) []byte { 31 | if len(k.pub) == PubKeyBytesLenCompressed { 32 | return k.pub 33 | } 34 | xs := hex.EncodeToString(k.pub[1:33]) 35 | ys := hex.EncodeToString(k.pub[33:]) 36 | x, _ := new(big.Int).SetString(xs, 16) 37 | y, _ := new(big.Int).SetString(ys, 16) 38 | b := make([]byte, 0, PubKeyBytesLenCompressed) 39 | format := pubkeyCompressed 40 | if isOdd(y) { 41 | format |= 0x1 42 | } 43 | b = append(b, format) 44 | return paddedAppend(32, b, x.Bytes()) 45 | } 46 | 47 | func isOdd(a *big.Int) bool { 48 | return a.Bit(0) == 1 49 | } 50 | 51 | func paddedAppend(size uint, dst, src []byte) []byte { 52 | for i := 0; i < int(size)-len(src); i++ { 53 | dst = append(dst, 0) 54 | } 55 | return append(dst, src...) 56 | } 57 | -------------------------------------------------------------------------------- /tokens/near/key.go: -------------------------------------------------------------------------------- 1 | package near 2 | 3 | import ( 4 | "encoding/hex" 5 | "math/big" 6 | ) 7 | 8 | const ( 9 | // PubKeyBytesLenCompressed is compressed pubkey byte length 10 | PubKeyBytesLenCompressed = 33 11 | // PubKeyBytesLenUncompressed is uncompressed pubkey byte length 12 | PubKeyBytesLenUncompressed = 65 13 | ) 14 | 15 | const ( 16 | pubkeyCompressed byte = 0x2 17 | ) 18 | 19 | // EcdsaPublic struct ripple ecdsa pubkey key 20 | type EcdsaPublic struct { 21 | pub []byte 22 | } 23 | 24 | // Private not used 25 | func (k *EcdsaPublic) Private(sequence *uint32) []byte { 26 | return nil 27 | } 28 | 29 | // Public returns pubkey bytes 30 | func (k *EcdsaPublic) Public(sequence *uint32) []byte { 31 | if len(k.pub) == PubKeyBytesLenCompressed { 32 | return k.pub 33 | } 34 | xs := hex.EncodeToString(k.pub[1:33]) 35 | ys := hex.EncodeToString(k.pub[33:]) 36 | x, _ := new(big.Int).SetString(xs, 16) 37 | y, _ := new(big.Int).SetString(ys, 16) 38 | b := make([]byte, 0, PubKeyBytesLenCompressed) 39 | format := pubkeyCompressed 40 | if isOdd(y) { 41 | format |= 0x1 42 | } 43 | b = append(b, format) 44 | return paddedAppend(32, b, x.Bytes()) 45 | } 46 | 47 | func isOdd(a *big.Int) bool { 48 | return a.Bit(0) == 1 49 | } 50 | 51 | func paddedAppend(size uint, dst, src []byte) []byte { 52 | for i := 0; i < int(size)-len(src); i++ { 53 | dst = append(dst, 0) 54 | } 55 | return append(dst, src...) 56 | } 57 | -------------------------------------------------------------------------------- /tokens/cardano/tools/newToken/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/common" 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | cardanosdk "github.com/echovl/cardano-go" 10 | "github.com/echovl/cardano-go/crypto" 11 | ) 12 | 13 | var ( 14 | paramAsset string 15 | paramPolicyKey string 16 | appendName bool 17 | ) 18 | 19 | func main() { 20 | log.SetLogger(6, false, true) 21 | 22 | initAll() 23 | 24 | if appendName { 25 | paramPolicyKey = paramPolicyKey + paramAsset 26 | } 27 | policyKey := crypto.NewXPrvKeyFromEntropy([]byte(paramPolicyKey), "") 28 | policyScript, err := cardanosdk.NewScriptPubKey(policyKey.PubKey()) 29 | if err != nil { 30 | panic(err) 31 | } 32 | policyID, err := cardanosdk.NewPolicyID(policyScript) 33 | if err != nil { 34 | panic(err) 35 | } 36 | assetName := cardanosdk.NewAssetName(paramAsset) 37 | 38 | assetNameWithPolicy := policyID.String() + "." + common.Bytes2Hex(assetName.Bytes()) 39 | fmt.Printf("asset: %s", assetNameWithPolicy) 40 | 41 | } 42 | 43 | func initAll() { 44 | initFlags() 45 | } 46 | 47 | func initFlags() { 48 | flag.BoolVar(&appendName, "append", false, "append asset name") 49 | flag.StringVar(¶mAsset, "asset", "", "asset eg. USDT") 50 | flag.StringVar(¶mPolicyKey, "key", "", "policy seed") 51 | 52 | flag.Parse() 53 | 54 | log.Info("init flags finished") 55 | } 56 | -------------------------------------------------------------------------------- /worker/reportstat.go: -------------------------------------------------------------------------------- 1 | package worker 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/mpc" 8 | "github.com/anyswap/CrossChain-Router/v3/params" 9 | "github.com/anyswap/CrossChain-Router/v3/rpc/client" 10 | ) 11 | 12 | var ( 13 | reportStatStarter sync.Once 14 | 15 | reportInterval = 120 * time.Second 16 | ) 17 | 18 | // StartReportStatJob report stat job 19 | func StartReportStatJob() { 20 | if params.GetRouterOracleConfig() == nil { 21 | return 22 | } 23 | reportStatStarter.Do(func() { 24 | logWorker("reportstat", "start report stat job") 25 | go reportStat() 26 | }) 27 | } 28 | 29 | func reportStat() { 30 | for { 31 | doReport() 32 | 33 | time.Sleep(reportInterval) 34 | } 35 | } 36 | 37 | func doReport() { 38 | method := "swap.ReportOracleInfo" 39 | timestamp := time.Now().Unix() 40 | args := map[string]interface{}{ 41 | "enode": mpc.GetMPCConfig(false).GetSelfEnode(), 42 | "timestamp": timestamp, 43 | } 44 | url := params.GetRouterOracleConfig().ServerAPIAddress 45 | var result string 46 | var err error 47 | for i := 0; i < 3; i++ { 48 | err = client.RPCPostWithTimeout(20, &result, url, method, args) 49 | if err == nil { 50 | break 51 | } 52 | } 53 | if err != nil { 54 | logWorkerWarn("reportstat", "report stat failed", "err", err) 55 | } else { 56 | logWorker("reportstat", "report stat success", "timestamp", timestamp) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tokens/flow/tools/scan/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | sdk "github.com/onflow/flow-go-sdk" 9 | "github.com/onflow/flow-go-sdk/access/grpc" 10 | ) 11 | 12 | var ( 13 | ctx = context.Background() 14 | url = "access.devnet.nodes.onflow.org:9000" 15 | eventType = "A.cb2d04fc89307107.JoyrideMultiToken.JoyrideMultiTokenInfoEvent" 16 | ) 17 | 18 | func main() { 19 | 20 | flowClient, err := grpc.NewClient(url) 21 | if err != nil { 22 | log.Fatal("connect failed", "url", url, "err", err) 23 | } 24 | 25 | result, err := flowClient.GetEventsForHeightRange(ctx, eventType, 73857392, 73857394) 26 | if err != nil { 27 | fmt.Printf("\n\nerr: %s", err) 28 | } 29 | allTransaction := printEvents(result) 30 | fmt.Printf("\n\nallTransaction: %s", allTransaction) 31 | } 32 | 33 | func printEvents(result []sdk.BlockEvents) []string { 34 | var allRes []string 35 | for _, block := range result { 36 | allRes = append(allRes, printEvent(block.Events)...) 37 | } 38 | return allRes 39 | } 40 | 41 | func printEvent(events []sdk.Event) []string { 42 | var res []string 43 | for _, event := range events { 44 | // fmt.Printf("\n\nType: %s", event.Type) 45 | // fmt.Printf("\nValues: %v", event.Value) 46 | // fmt.Printf("\nTransaction ID: %s", event.TransactionID) 47 | res = append(res, event.TransactionID.String()) 48 | } 49 | return res 50 | } 51 | -------------------------------------------------------------------------------- /tokens/near/tools/README.md: -------------------------------------------------------------------------------- 1 | ## tools for call to near by mpc publicKey 2 | 3 | ### deployContract 4 | ```text 5 | go run ./tokens/near/tools/deployContract/main.go -config ./build/bin/config-sign-with-privatekey-example.toml -chainID 1001313161555 -pubKey ed25519:7SVZCtsvrQmmAk9q5Ds4eZxKHWpgkQTSwNud5kn9JLiK -privKey ed25519:5NNdYaMoxpKZNTft2vrfx11tt9Lk5W7Zo3dkJkGRmZboEEHYEiJUzowdMWqTXSgfMKQcWNmD17zTdXrViRCsmTmH -accountId test.userdemo.testnet 6 | ``` 7 | 8 | ### changeMpc 9 | > go run functionCall/main.go -config config.toml -chainID xxx -routerContract xxx -functionName change_mpc_id -newMpcId xxx -pubKey xxx 10 | 11 | ### setBaseGas 12 | > go run functionCall/main.go -config config.toml -chainID xxx -routerContract xxx -functionName set_base_gas -newGas xxx -pubKey xxx 13 | 14 | ### setGas 15 | > go run functionCall/main.go -config config.toml -chainID xxx -routerContract xxx -functionName set_gas -newGas xxx -token xxx -pubKey xxx 16 | 17 | ### anySwapInAll 18 | > go run functionCall/main.go -config config.toml -chainID xxx -routerContract xxx -functionName any_swap_in_all -txHash xxx -token xxx -to xxx -amount xxx -fromChainId xxx -pubKey xxx 19 | 20 | ### changeWnative 21 | > go run functionCall/main.go -config config.toml -chainID xxx -routerContract xxx -functionName change_wnative -newWnative xxx -pubKey xxx 22 | 23 | ### sendNear 24 | > go run sendNear/main.go -config config.toml -chainID xxx -to xxx -amount xxx -pubKey xxx 25 | 26 | 27 | -------------------------------------------------------------------------------- /tokens/iota/tools/publicKeyToAddress/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/hex" 6 | "flag" 7 | "fmt" 8 | "time" 9 | 10 | "github.com/anyswap/CrossChain-Router/v3/log" 11 | iotago "github.com/iotaledger/iota.go/v2" 12 | ) 13 | 14 | var ( 15 | paramPubKey string 16 | paramNetwork string 17 | ) 18 | 19 | func initFlags() { 20 | flag.StringVar(¶mPubKey, "publicKey", "", "public key string") 21 | flag.StringVar(¶mNetwork, "p", "", "network url") 22 | flag.Parse() 23 | } 24 | 25 | func main() { 26 | log.SetLogger(6, false, true) 27 | 28 | initFlags() 29 | 30 | // create a new node API client 31 | nodeHTTPAPIClient := iotago.NewNodeHTTPAPIClient(paramNetwork) 32 | ctx, cancelFunc := context.WithTimeout(context.Background(), 15*time.Second) 33 | defer cancelFunc() 34 | 35 | // fetch the node's info to know the min. required PoW score 36 | if info, err := nodeHTTPAPIClient.Info(ctx); err != nil { 37 | log.Fatal("Info", "paramNetwork", paramNetwork, "err", err) 38 | } else { 39 | fmt.Printf("info: %+v\n", info) 40 | 41 | if publicKey, err := hex.DecodeString(paramPubKey); err != nil { 42 | log.Fatal("DecodeString", "paramPubKey", paramPubKey, "err", err) 43 | } else { 44 | edAddr := iotago.AddressFromEd25519PubKey(publicKey) 45 | bech32Addr := edAddr.Bech32(iotago.NetworkPrefix(info.Bech32HRP)) 46 | fmt.Printf("edAddr: %+v\niotaAddr: %+v\n", edAddr.String(), bech32Addr) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tokens/solana/types/account.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // Account account type 8 | type Account struct { 9 | PrivateKey PrivateKey 10 | } 11 | 12 | // NewAccount new account 13 | func NewAccount() *Account { 14 | _, privateKey, err := NewRandomPrivateKey() 15 | if err != nil { 16 | panic(fmt.Sprintf("failed to generate private key: %s", err)) 17 | } 18 | return &Account{ 19 | PrivateKey: privateKey, 20 | } 21 | } 22 | 23 | // AccountFromPrivateKeyBase58 account from private key base58 24 | func AccountFromPrivateKeyBase58(privateKey string) (*Account, error) { 25 | k, err := PrivateKeyFromBase58(privateKey) 26 | if err != nil { 27 | return nil, fmt.Errorf("account from private key: private key from b58: %w", err) 28 | } 29 | return &Account{ 30 | PrivateKey: k, 31 | }, nil 32 | } 33 | 34 | // PublicKey get account public key 35 | func (a *Account) PublicKey() PublicKey { 36 | return a.PrivateKey.PublicKey() 37 | } 38 | 39 | // AccountSettable interface 40 | type AccountSettable interface { 41 | SetAccounts(accounts []*AccountMeta) error 42 | } 43 | 44 | // AccountMeta account meta type 45 | type AccountMeta struct { 46 | PublicKey PublicKey 47 | IsSigner bool 48 | IsWritable bool 49 | } 50 | 51 | func (a *AccountMeta) less(act *AccountMeta) bool { 52 | if a.IsSigner != act.IsSigner { 53 | return a.IsSigner 54 | } 55 | if a.IsWritable != act.IsWritable { 56 | return a.IsWritable 57 | } 58 | return false 59 | } 60 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/crypto/ed25519.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "bytes" 5 | "crypto/ed25519" 6 | "crypto/rand" 7 | "fmt" 8 | ) 9 | 10 | type ed25519key struct { 11 | priv ed25519.PrivateKey 12 | } 13 | 14 | func checkSequenceIsNil(seq *uint32) { 15 | if seq != nil { 16 | panic("Ed25519 keys do not support account families") 17 | } 18 | } 19 | 20 | func (e *ed25519key) Id(seq *uint32) []byte { 21 | checkSequenceIsNil(seq) 22 | return Sha256RipeMD160(e.Public(seq)) 23 | } 24 | 25 | func (e *ed25519key) Public(seq *uint32) []byte { 26 | checkSequenceIsNil(seq) 27 | return append([]byte{0xED}, e.priv[32:]...) 28 | } 29 | 30 | func (e *ed25519key) Private(seq *uint32) []byte { 31 | checkSequenceIsNil(seq) 32 | return e.priv[:] 33 | } 34 | 35 | func NewEd25519Key(seed []byte) (*ed25519key, error) { 36 | r := rand.Reader 37 | if seed != nil { 38 | r = bytes.NewReader(Sha512Half(seed)) 39 | } 40 | _, priv, err := ed25519.GenerateKey(r) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return &ed25519key{priv: priv}, nil 45 | } 46 | 47 | // NewEd25519KeyFromPrivKeyBytes new Ed25519 key from private key bytes 48 | func NewEd25519KeyFromPrivKeyBytes(privKeyBytes []byte) *ed25519key { 49 | if len(privKeyBytes) != ed25519.PrivateKeySize { 50 | panic(fmt.Sprintf("wrong ed25519 private key bytes length, want %v, have %v", ed25519.PrivateKeySize, len(privKeyBytes))) 51 | } 52 | return &ed25519key{priv: ed25519.PrivateKey(privKeyBytes)} 53 | } 54 | -------------------------------------------------------------------------------- /types/transaction_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/common" 7 | ) 8 | 9 | type txHashTest struct { 10 | rawtx string 11 | want string 12 | } 13 | 14 | var ( 15 | txHashTests = []txHashTest{ 16 | { // eth 17 | "0xf86e8231a0843b9aca64825208949873d61e6bf850d0b0c2f3c6e075980683f2d9fe87038d7ea4c6800080820136a093a2e1ead7f960623fb5d46c8605135d258f87e202df8ec5509567633618b367a05d236da2259cc584b2906493957d04ec00afa7d6e97568eac61281bb798b5302", 18 | "0xa8fb350068349a2593661deb21729ca32012cf59520fe4f0b8fd82cd8737a548", 19 | }, 20 | { // eth type 2 (eip1559 dynamic fee tx) 21 | "0x02f891038221e2843b9aca00843b9aca10830109b194593cc1a399a65d3eaf8316da933745c4f5b9442980a40c4c4285ec7a95254a0d413d33ae00355127da335aa3388793f0eaa2bd39937f6b36dd0dc080a0694f25018b0a857e0a8fb5ca452d740bfd9870d56413cf5393d0a1cbac2fd10ea00c90354efed7947f617041b58741a2dc319ba6075f7f70ff8cb1eb15db8baa98", 22 | "0x78fe88e8dfbc3b62773121d6b73a21d0e7b798290cbea00eeee5f6a03f8292f1", 23 | }, 24 | } 25 | ) 26 | 27 | func TestTxHash(t *testing.T) { 28 | for _, test := range txHashTests { 29 | tx := new(Transaction) 30 | if err := tx.UnmarshalBinary(common.FromHex(test.rawtx)); err != nil { 31 | t.Errorf("rawtx: %s, tx unmarshal error: %v", test.rawtx, err) 32 | } 33 | hash := tx.Hash().Hex() 34 | if hash != test.want { 35 | t.Errorf("rawtx %s: hash mismatch, have %s, want %s", test.rawtx, hash, test.want) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/ledger.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | type LedgerHeader struct { 4 | LedgerSequence uint32 `json:"ledger_index,string"` 5 | TotalXRP uint64 `json:"total_coins,string"` 6 | PreviousLedger Hash256 `json:"parent_hash"` 7 | TransactionHash Hash256 `json:"transaction_hash"` 8 | StateHash Hash256 `json:"account_hash"` 9 | ParentCloseTime RippleTime `json:"parent_close_time"` 10 | CloseTime RippleTime `json:"close_time"` 11 | CloseResolution uint8 `json:"close_time_resolution"` 12 | CloseFlags uint8 `json:"close_flags"` 13 | } 14 | 15 | type Ledger struct { 16 | LedgerHeader 17 | Hash Hash256 `json:"hash"` 18 | Closed bool `json:"closed"` 19 | Accepted bool `json:"accepted"` 20 | Transactions TransactionSlice `json:"transactions,omitempty"` 21 | AccountState LedgerEntrySlice `json:"accountState,omitempty"` 22 | } 23 | 24 | func NewEmptyLedger(sequence uint32) *Ledger { 25 | return &Ledger{ 26 | LedgerHeader: LedgerHeader{ 27 | LedgerSequence: sequence, 28 | }, 29 | } 30 | } 31 | 32 | func (l Ledger) GetType() string { return "LedgerMaster" } 33 | func (l Ledger) Prefix() HashPrefix { return HP_LEDGER_MASTER } 34 | func (l Ledger) NodeType() NodeType { return NT_LEDGER } 35 | func (l Ledger) Ledger() uint32 { return l.LedgerSequence } 36 | func (l Ledger) NodeId() *Hash256 { return &l.Hash } 37 | func (l Ledger) GetHash() *Hash256 { return &l.Hash } 38 | -------------------------------------------------------------------------------- /tokens/near/address.go: -------------------------------------------------------------------------------- 1 | package near 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/common" 8 | "github.com/anyswap/CrossChain-Router/v3/tokens" 9 | ) 10 | 11 | // IsValidAddress check address 12 | func (b *Bridge) IsValidAddress(address string) bool { 13 | return address != "" 14 | } 15 | 16 | func (b *Bridge) GetAccountNonce(account, publicKey string) (uint64, error) { 17 | urls := b.GatewayConfig.AllGatewayURLs 18 | for _, url := range urls { 19 | result, err := GetAccountNonce(url, account, publicKey) 20 | if err == nil { 21 | return result, nil 22 | } 23 | } 24 | return 0, tokens.ErrGetAccountNonce 25 | } 26 | 27 | // PublicKeyToAddress public key hex string (may be uncompressed) to address 28 | func (b *Bridge) PublicKeyToAddress(pubKeyHex string) (string, error) { 29 | nearPubKey, err := PublicKeyFromHexString(pubKeyHex) 30 | if err != nil { 31 | return "", err 32 | } 33 | return nearPubKey.Address(), nil 34 | } 35 | 36 | func (b *Bridge) VerifyPubKey(address, pubkey string) error { 37 | nearPubKey, err := PublicKeyFromString(pubkey) 38 | if err != nil { 39 | return err 40 | } 41 | if common.IsHexHash(address) { 42 | if !strings.EqualFold(nearPubKey.Address(), address) { 43 | return fmt.Errorf("address %v and public key %v is not match", address, pubkey) 44 | } 45 | } 46 | _, err = b.GetAccountNonce(address, pubkey) 47 | if err != nil { 48 | return fmt.Errorf("verify public key failed, %w", err) 49 | } 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /tokens/cosmos/grpc/retry/retry.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/pkg/errors" 8 | ) 9 | 10 | // Retryable returns retryable error 11 | func Retryable(err error) error { 12 | if err == nil { 13 | return nil 14 | } 15 | return RetryableError{err: err} 16 | } 17 | 18 | // RetryableError represents retryable error 19 | type RetryableError struct { 20 | err error 21 | } 22 | 23 | // Error returns string representation of error 24 | func (e RetryableError) Error() string { 25 | return e.err.Error() 26 | } 27 | 28 | // Unwrap returns next error 29 | func (e RetryableError) Unwrap() error { 30 | return e.err 31 | } 32 | 33 | // Do retries running function until it returns non-retryable error 34 | func Do(ctx context.Context, retryAfter time.Duration, fn func() error) error { 35 | var lastMessage string 36 | var r RetryableError 37 | for { 38 | var r2 RetryableError 39 | if err := fn(); !errors.As(err, &r2) { 40 | return err 41 | } 42 | if errors.Is(r2.err, ctx.Err()) { 43 | if errors.Is(ctx.Err(), context.DeadlineExceeded) && r.err != nil { 44 | return r.err 45 | } 46 | return r2.err 47 | } 48 | r = r2 49 | 50 | newMessage := r.err.Error() 51 | if lastMessage != newMessage { 52 | lastMessage = newMessage 53 | } 54 | 55 | select { 56 | case <-ctx.Done(): 57 | if errors.Is(ctx.Err(), context.DeadlineExceeded) { 58 | return r.err 59 | } 60 | return errors.WithStack(ctx.Err()) 61 | case <-time.After(retryAfter): 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tokens/tests/config/config-test.toml: -------------------------------------------------------------------------------- 1 | # router swap identifier, must have prefix 'routerswap' 2 | Identifier = "routerswap#test" 3 | 4 | # router swap type (eg. erc20swap, nftswap, anycallswap) 5 | SwapType = "erc20swap" 6 | 7 | # test module name 8 | Module = "btc" 9 | 10 | # rpc listen port 11 | Port = 11556 12 | 13 | # use private key instead of mpc signing 14 | SignWithPrivateKey = "cQe83zjzDkDZHg4fN5BK9b9PY4TNnfnDh2mzCZL3Dp333ripJTEX" 15 | SignerAddress = "mw3Vr9dERAsJZZXEF9Xbi4tuB6xCAp3L2r" 16 | 17 | # allow call into router from contract 18 | AllowCallByContract = false 19 | 20 | # is debug mode (print more logs) 21 | IsDebugMode = true 22 | 23 | # all chain ids (pass 'miss token config' checking) 24 | AllChainIDs = ["1000004346948", "4"] 25 | 26 | [Gateway] 27 | APIAddress = ["https://blockstream.info/testnet/api"] 28 | 29 | # chain config 30 | [Chain] 31 | BlockChain = "btc" 32 | ChainID = "1000004346948" 33 | Confirmations = 1 34 | InitialHeight = 0 35 | RouterContract = "0x92c079d3155c2722dbf7e65017a5baf9cd15561c" 36 | 37 | # token config 38 | [Token] 39 | ContractAddress = "0x49974c3c99f4e74d08845c31d3f4f16fdc264ebd" 40 | ContractVersion = 6 41 | Decimals = 8 42 | RouterContract = "0x92c079d3155c2722dbf7e65017a5baf9cd15561c" 43 | TokenID = "btc" 44 | Underlying = "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c" 45 | 46 | [Swap] 47 | BigValueThreshold = "10000000000000000000000000" 48 | MaximumSwap = "10000000000000000000000000" 49 | MaximumSwapFee = "0" 50 | MinimumSwap = "1" 51 | MinimumSwapFee = "0" 52 | SwapFeeRatePerMillion = 0 53 | -------------------------------------------------------------------------------- /admin/utils.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/cmd/utils" 7 | "github.com/anyswap/CrossChain-Router/v3/rpc/client" 8 | "github.com/urfave/cli/v2" 9 | ) 10 | 11 | // common flags 12 | var ( 13 | swapServer string 14 | 15 | CommonFlags = []cli.Flag{ 16 | utils.SwapServerFlag, 17 | utils.KeystoreFileFlag, 18 | utils.PasswordFileFlag, 19 | } 20 | ) 21 | 22 | // SwapAdmin rpc call server `swap.AdminCall` 23 | func SwapAdmin(method string, params []string) (result interface{}, err error) { 24 | rawTx, err := Sign(method, params) 25 | if err != nil { 26 | return "", err 27 | } 28 | timeout := 300 29 | reqID := 1010 30 | err = client.RPCPostWithTimeoutAndID(&result, timeout, reqID, swapServer, "swap.AdminCall", rawTx) 31 | return result, err 32 | } 33 | 34 | func loadKeyStore(ctx *cli.Context) error { 35 | keyfile := ctx.String(utils.KeystoreFileFlag.Name) 36 | passfile := ctx.String(utils.PasswordFileFlag.Name) 37 | return LoadKeyStore(keyfile, passfile) 38 | } 39 | 40 | func initSwapServer(ctx *cli.Context) error { 41 | swapServer = ctx.String(utils.SwapServerFlag.Name) 42 | if swapServer == "" { 43 | return errors.New("must specify swapserver") 44 | } 45 | return nil 46 | } 47 | 48 | // Prepare load keystore and init server 49 | func Prepare(ctx *cli.Context) (err error) { 50 | err = loadKeyStore(ctx) 51 | if err != nil { 52 | return err 53 | } 54 | 55 | err = initSwapServer(ctx) 56 | if err != nil { 57 | return err 58 | } 59 | 60 | return nil 61 | } 62 | -------------------------------------------------------------------------------- /tools/rlp/encoder_example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The go-ethereum Authors 2 | // This file is part of the go-ethereum library. 3 | // 4 | // The go-ethereum library is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Lesser General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // The go-ethereum library is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with the go-ethereum library. If not, see . 16 | 17 | package rlp 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | ) 23 | 24 | type MyCoolType struct { 25 | Name string 26 | a, b uint 27 | } 28 | 29 | // EncodeRLP writes x as RLP list [a, b] that omits the Name field. 30 | func (x *MyCoolType) EncodeRLP(w io.Writer) (err error) { 31 | return Encode(w, []uint{x.a, x.b}) 32 | } 33 | 34 | func ExampleEncoder() { 35 | var t *MyCoolType // t is nil pointer to MyCoolType 36 | bytes, _ := EncodeToBytes(t) 37 | fmt.Printf("%v → %X\n", t, bytes) 38 | 39 | t = &MyCoolType{Name: "foobar", a: 5, b: 6} 40 | bytes, _ = EncodeToBytes(t) 41 | fmt.Printf("%v → %X\n", t, bytes) 42 | 43 | // Output: 44 | // → C0 45 | // &{foobar 5 6} → C20506 46 | } 47 | -------------------------------------------------------------------------------- /leveldb/batch.go: -------------------------------------------------------------------------------- 1 | // Package leveldb - leveldb wrapper 2 | //nolint 3 | package leveldb 4 | 5 | // Batch is a write-only database that commits changes to its host database 6 | // when Write is called. A batch cannot be used concurrently. 7 | type Batch interface { 8 | KeyValueWriter 9 | 10 | // ValueSize retrieves the amount of data queued up for writing. 11 | ValueSize() int 12 | 13 | // Write flushes any accumulated data to disk. 14 | Write() error 15 | 16 | // Reset resets the batch for reuse. 17 | Reset() 18 | 19 | // Replay replays the batch contents. 20 | Replay(w KeyValueWriter) error 21 | } 22 | 23 | // Batcher wraps the NewBatch method of a backing data store. 24 | type Batcher interface { 25 | // NewBatch creates a write-only database that buffers changes to its host db 26 | // until a final write is called. 27 | NewBatch() Batch 28 | } 29 | 30 | // HookedBatch wraps an arbitrary batch where each operation may be hooked into 31 | // to monitor from black box code. 32 | type HookedBatch struct { 33 | Batch 34 | 35 | OnPut func(key []byte, value []byte) // Callback if a key is inserted 36 | OnDelete func(key []byte) // Callback if a key is deleted 37 | } 38 | 39 | // Put inserts the given value into the key-value data store. 40 | func (b HookedBatch) Put(key []byte, value []byte) error { 41 | if b.OnPut != nil { 42 | b.OnPut(key, value) 43 | } 44 | return b.Batch.Put(key, value) 45 | } 46 | 47 | // Delete removes the key from the key-value data store. 48 | func (b HookedBatch) Delete(key []byte) error { 49 | if b.OnDelete != nil { 50 | b.OnDelete(key) 51 | } 52 | return b.Batch.Delete(key) 53 | } 54 | -------------------------------------------------------------------------------- /tokens/flow/transaction/Init.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | import AnyToken from %s 3 | import AnyExampleToken from %s 4 | import Router from %s 5 | 6 | transaction() { 7 | let minterStoragePath: StoragePath 8 | let minterPrivatePath: PrivatePath 9 | let routerRef : Capability<&{AnyToken.IMinter}> 10 | let mpcStoragePath: StoragePath 11 | let mpcRef: &Router.Mpc 12 | 13 | prepare(acct: AuthAccount) { 14 | self.minterStoragePath= /storage/anyExampleTokenMinter 15 | self.minterPrivatePath= /private/anyExampleTokenMinter 16 | self.mpcStoragePath=/storage/routerMpc 17 | 18 | acct.link<&{AnyToken.IMinter}>( 19 | self.minterPrivatePath, 20 | target: self.minterStoragePath 21 | ) 22 | self.mpcRef=acct.borrow<&Router.Mpc>(from:self.mpcStoragePath) 23 | ?? panic("Could not borrow a reference to the crosschain") 24 | if !acct.getCapability<&{AnyToken.IMinter}>(self.minterPrivatePath).check() { 25 | acct.link<&{AnyToken.IMinter}>(self.minterPrivatePath, target: self.minterStoragePath) 26 | } 27 | 28 | self.routerRef=acct.getCapability<&{AnyToken.IMinter}>(self.minterPrivatePath) 29 | } 30 | 31 | execute{ 32 | let token=AnyExampleToken.Vault 33 | self.mpcRef.insertAnyToken(key:token.getType().identifier, value: self.routerRef) 34 | log("token:".concat(token.getType().identifier)) 35 | log(Router.containsAnyToken(token: token.getType().identifier)) 36 | log("routerRefIdentifier:".concat(self.routerRef.getType().identifier)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /common/hexutil/json_example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The go-ethereum Authors 2 | // This file is part of the go-ethereum library. 3 | // 4 | // The go-ethereum library is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Lesser General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // The go-ethereum library is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with the go-ethereum library. If not, see . 16 | 17 | package hexutil_test 18 | 19 | import ( 20 | "encoding/json" 21 | "fmt" 22 | 23 | "github.com/anyswap/CrossChain-Router/v3/common/hexutil" 24 | ) 25 | 26 | type MyType [5]byte 27 | 28 | func (v *MyType) UnmarshalText(input []byte) error { 29 | return hexutil.UnmarshalFixedText("MyType", input, v[:]) 30 | } 31 | 32 | func (v MyType) String() string { 33 | return hexutil.Bytes(v[:]).String() 34 | } 35 | 36 | func ExampleUnmarshalFixedText() { 37 | var v1, v2 MyType 38 | fmt.Println("v1 error:", json.Unmarshal([]byte(`"0x01"`), &v1)) 39 | fmt.Println("v2 error:", json.Unmarshal([]byte(`"0x0101010101"`), &v2)) 40 | fmt.Println("v2:", v2) 41 | // Output: 42 | // v1 error: hex string has length 2, want 10 for MyType 43 | // v2 error: 44 | // v2: 0x0101010101 45 | } 46 | -------------------------------------------------------------------------------- /tokens/eth/sendtx.go: -------------------------------------------------------------------------------- 1 | package eth 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/log" 7 | "github.com/anyswap/CrossChain-Router/v3/params" 8 | "github.com/anyswap/CrossChain-Router/v3/types" 9 | ) 10 | 11 | func (b *Bridge) SendZKSyncTransaction(signedTx interface{}) (txHash string, err error) { 12 | tx, ok := signedTx.(*SignedZKSyncTx) 13 | if !ok { 14 | log.Printf("signed tx is %+v", signedTx) 15 | return "", errors.New("wrong signed transaction type") 16 | } 17 | txHash, err = b.SendSignedZKSyncTransaction(tx.Raw) 18 | chainID := b.ChainConfig.ChainID 19 | if err != nil { 20 | log.Info("SendTransaction failed", "chainID", chainID, "hash", txHash, "err", err) 21 | } else { 22 | log.Info("SendTransaction success", "chainID", chainID, "hash", txHash) 23 | } 24 | return txHash, err 25 | } 26 | 27 | // SendTransaction send signed tx 28 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 29 | if b.IsZKSync() { 30 | return b.SendZKSyncTransaction(signedTx) 31 | } 32 | tx, ok := signedTx.(*types.Transaction) 33 | if !ok { 34 | log.Printf("signed tx is %+v", signedTx) 35 | return "", errors.New("wrong signed transaction type") 36 | } 37 | chainID := b.ChainConfig.ChainID 38 | txHash, err = b.SendSignedTransaction(tx) 39 | if err != nil { 40 | log.Info("SendTransaction failed", "chainID", chainID, "hash", txHash, "err", err) 41 | } else { 42 | log.Info("SendTransaction success", "chainID", chainID, "hash", txHash) 43 | } 44 | if params.IsDebugMode() { 45 | log.Infof("SendTransaction on chain %v, rawtx is %v", chainID, tx.RawStr()) 46 | } 47 | return txHash, err 48 | } 49 | -------------------------------------------------------------------------------- /tokens/iota/tools/keygen/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "flag" 6 | "fmt" 7 | "math/rand" 8 | "time" 9 | 10 | "github.com/anyswap/CrossChain-Router/v3/common" 11 | "github.com/anyswap/CrossChain-Router/v3/log" 12 | "github.com/anyswap/CrossChain-Router/v3/tokens/iota" 13 | iotago "github.com/iotaledger/iota.go/v2" 14 | "github.com/iotaledger/iota.go/v2/ed25519" 15 | ) 16 | 17 | var ( 18 | paramNetwork string 19 | addrPrefix string 20 | ) 21 | 22 | func initFlags() { 23 | flag.StringVar(¶mNetwork, "p", "devnet", "network, eg. mainnet, or devnet.") 24 | flag.Parse() 25 | } 26 | 27 | func main() { 28 | initFlags() 29 | 30 | network := paramNetwork 31 | switch network { 32 | case "mainnet": 33 | addrPrefix = string(iotago.PrefixMainnet) 34 | case "devnet": 35 | addrPrefix = string(iotago.PrefixTestnet) 36 | default: 37 | log.Fatal("invalid network, choose mainnet or devnet") 38 | } 39 | 40 | pubKey, privKey, err := GenerateKey() 41 | if err != nil { 42 | log.Fatalf("key gen failed, error: %v", err) 43 | } 44 | 45 | pubKeyStr := common.Bytes2Hex(pubKey) 46 | addr := iota.ConvertPubKeyToAddr(pubKeyStr) 47 | bech32Addr := addr.Bech32(iotago.NetworkPrefix(addrPrefix)) 48 | fmt.Printf("Generated random keys: \n") 49 | fmt.Printf("Address: %s\n", bech32Addr) 50 | fmt.Printf("Public Key: %s\n", pubKeyStr) 51 | fmt.Printf("Private Key: %s\n", common.Bytes2Hex(privKey)) 52 | } 53 | 54 | func GenerateKey() (ed25519.PublicKey, ed25519.PrivateKey, error) { 55 | rand.Seed(time.Now().UnixNano()) 56 | seed := make([]byte, ed25519.SeedSize) 57 | rand.Read(seed) 58 | return ed25519.GenerateKey(bytes.NewReader(seed)) 59 | } 60 | -------------------------------------------------------------------------------- /tokens/ripple/sendtx.go: -------------------------------------------------------------------------------- 1 | package ripple 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | "github.com/anyswap/CrossChain-Router/v3/rpc/client" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens" 10 | "github.com/anyswap/CrossChain-Router/v3/tokens/ripple/rubblelabs/ripple/data" 11 | "github.com/anyswap/CrossChain-Router/v3/tokens/ripple/rubblelabs/ripple/websockets" 12 | ) 13 | 14 | // SendTransaction send signed tx 15 | func (b *Bridge) SendTransaction(signedTx interface{}) (txHash string, err error) { 16 | tx, ok := signedTx.(data.Transaction) 17 | if !ok { 18 | return "", tokens.ErrWrongRawTx 19 | } 20 | _, raw, err := data.Raw(tx) 21 | if err != nil { 22 | return "", err 23 | } 24 | rpcParams := map[string]interface{}{ 25 | "tx_blob": fmt.Sprintf("%X", raw), 26 | } 27 | var success bool 28 | urls := b.GetGatewayConfig().AllGatewayURLs 29 | for i := 0; i < rpcRetryTimes; i++ { 30 | // try send to all remotes 31 | for _, url := range urls { 32 | var resp *websockets.SubmitResult 33 | err = client.RPCPostWithTimeout(b.RPCClientTimeout, &resp, url, "submit", rpcParams) 34 | if err != nil || resp == nil { 35 | log.Warn("Try sending transaction failed", "error", err) 36 | continue 37 | } 38 | if !resp.EngineResult.Success() { 39 | log.Warn("send tx with error result", "result", resp.EngineResult, "message", resp.EngineResultMessage) 40 | } 41 | txHash = tx.GetBase().Hash.String() 42 | success = true 43 | } 44 | if success { 45 | break 46 | } 47 | time.Sleep(rpcRetryInterval) 48 | } 49 | if success { 50 | return txHash, nil 51 | } 52 | return "", err 53 | } 54 | -------------------------------------------------------------------------------- /tools/weightedstring.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | // WeightedString weighted string 9 | type WeightedString struct { 10 | Content string 11 | Weight uint64 12 | } 13 | 14 | // WeightedStringSlice weighted string slice 15 | type WeightedStringSlice []*WeightedString 16 | 17 | // Len impl Sortable 18 | func (s WeightedStringSlice) Len() int { 19 | return len(s) 20 | } 21 | 22 | // Swap impl Sortable 23 | func (s WeightedStringSlice) Swap(i, j int) { 24 | s[i], s[j] = s[j], s[i] 25 | } 26 | 27 | // Less impl Sortable 28 | func (s WeightedStringSlice) Less(i, j int) bool { 29 | return s[i].Weight > s[j].Weight 30 | } 31 | 32 | // Add add item 33 | func (s WeightedStringSlice) Add(content string, weight uint64) WeightedStringSlice { 34 | s = append(s, &WeightedString{ 35 | Content: content, 36 | Weight: weight, 37 | }) 38 | return s 39 | } 40 | 41 | // Reverse reverse items 42 | func (s WeightedStringSlice) Reverse() { 43 | length := s.Len() 44 | for i := 0; i < length/2; i++ { 45 | s.Swap(i, length-i-1) 46 | } 47 | } 48 | 49 | // Sort sort items 50 | func (s WeightedStringSlice) Sort() WeightedStringSlice { 51 | sort.Stable(s) 52 | return s 53 | } 54 | 55 | // GetStrings get strings (commonly sort at first) 56 | func (s WeightedStringSlice) GetStrings() (result []string) { 57 | for _, wstr := range s { 58 | result = append(result, wstr.Content) 59 | } 60 | return result 61 | } 62 | 63 | func (s WeightedStringSlice) String() (result string) { 64 | result += "[" 65 | for _, wstr := range s { 66 | result += fmt.Sprintf(" (%v, %v) ", wstr.Content, wstr.Weight) 67 | } 68 | result += "]" 69 | return result 70 | } 71 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/data/time.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | const ( 8 | rippleTimeEpoch int64 = 946684800 9 | rippleTimeFormat string = "2006-Jan-02 15:04:05 UTC" 10 | ) 11 | 12 | // Represents a time as the number of seconds since the Ripple epoch: January 1st, 2000 (00:00 UTC) 13 | type RippleTime struct { 14 | T uint32 15 | } 16 | 17 | type rippleHumanTime struct { 18 | RippleTime 19 | } 20 | 21 | func NewRippleTime(t uint32) *RippleTime { 22 | return &RippleTime{t} 23 | } 24 | 25 | func convertToRippleTime(t time.Time) uint32 { 26 | return uint32(t.Sub(time.Unix(rippleTimeEpoch, 0)).Nanoseconds() / 1000000000) 27 | } 28 | 29 | func (t RippleTime) Time() time.Time { 30 | return time.Unix(int64(t.T)+rippleTimeEpoch, 0) 31 | } 32 | 33 | func Now() *RippleTime { 34 | return &RippleTime{convertToRippleTime(time.Now())} 35 | } 36 | 37 | // Accepts time formatted as 2006-Jan-02 15:04:05 38 | func (t *RippleTime) SetString(s string) error { 39 | v, err := time.Parse(rippleTimeFormat, s) 40 | if err != nil { 41 | return err 42 | } 43 | t.SetUint32(convertToRippleTime(v)) 44 | return nil 45 | } 46 | 47 | func (t *RippleTime) SetUint32(n uint32) { 48 | t.T = n 49 | } 50 | 51 | func (t RippleTime) Uint32() uint32 { 52 | return t.T 53 | } 54 | 55 | func (t RippleTime) human() *rippleHumanTime { 56 | return &rippleHumanTime{t} 57 | } 58 | 59 | // Returns time formatted as 2006-Jan-02 15:04:05 60 | func (t RippleTime) String() string { 61 | return t.Time().UTC().Format(rippleTimeFormat) 62 | } 63 | 64 | // Returns time formatted as 15:04:05 65 | func (t RippleTime) Short() string { 66 | return t.Time().UTC().Format("15:04:05") 67 | } 68 | -------------------------------------------------------------------------------- /tokens/eth/callapi/conflux.go: -------------------------------------------------------------------------------- 1 | package callapi 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/common" 5 | "github.com/anyswap/CrossChain-Router/v3/common/hexutil" 6 | "github.com/anyswap/CrossChain-Router/v3/rpc/client" 7 | "github.com/anyswap/CrossChain-Router/v3/types" 8 | ) 9 | 10 | // ------------------------ conflux override apis ----------------------------- 11 | 12 | // CfxBlock struct 13 | type CfxBlock struct { 14 | Hash *common.Hash `json:"hash"` 15 | ParentHash *common.Hash `json:"parentHash"` 16 | EpochNumber *hexutil.Big `json:"epochNumber"` 17 | BlockNumber *hexutil.Big `json:"blockNumber"` 18 | } 19 | 20 | // CfxGetBlockConfirmations get block confirmations 21 | func CfxGetBlockConfirmations(b EvmBridge, receipt *types.RPCTxReceipt) (uint64, error) { 22 | latest, err := CfxGetFinalizedBlockNumber(b) 23 | if err != nil { 24 | return 0, err 25 | } 26 | blockNumber := receipt.BlockNumber.ToInt().Uint64() 27 | if latest > blockNumber { 28 | return latest - blockNumber, nil 29 | } 30 | return 0, nil 31 | } 32 | 33 | // CfxGetFinalizedBlockNumber call cfx_getBlockByEpochNumber 34 | func CfxGetFinalizedBlockNumber(b EvmBridge) (latest uint64, err error) { 35 | urls := b.GetGatewayConfig().FinalizeAPIAddress 36 | var maxHeight uint64 37 | for _, url := range urls { 38 | var result *CfxBlock 39 | err = client.RPCPost(&result, url, "cfx_getBlockByEpochNumber", "latest_finalized", false) 40 | if err == nil && result != nil { 41 | h := result.EpochNumber.ToInt().Uint64() 42 | if h > maxHeight { 43 | maxHeight = h 44 | } 45 | } 46 | } 47 | if maxHeight > 0 { 48 | return maxHeight, nil 49 | } 50 | return 0, wrapRPCQueryError(err, "cfx_getBlockByEpochNumber") 51 | } 52 | -------------------------------------------------------------------------------- /tokens/solana/address.go: -------------------------------------------------------------------------------- 1 | package solana 2 | 3 | import ( 4 | "crypto/ed25519" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/common" 9 | "github.com/anyswap/CrossChain-Router/v3/log" 10 | "github.com/anyswap/CrossChain-Router/v3/tokens/solana/types" 11 | ) 12 | 13 | // IsValidAddress impl check address 14 | func (b *Bridge) IsValidAddress(address string) bool { 15 | if b.IsNative(address) { 16 | return true 17 | } 18 | _, err := types.PublicKeyFromBase58(address) 19 | return err == nil 20 | } 21 | 22 | func (b *Bridge) IsNative(address string) bool { 23 | return strings.ToLower(address) == "native" 24 | } 25 | 26 | // VerifyMPCPubKey verify mpc address and public key is matching 27 | func (b *Bridge) VerifyMPCPubKey(mpcAddress, mpcPubkey string) error { 28 | pubAddr, err := PublicKeyToAddress(mpcPubkey) 29 | log.Info("VerifyMPCPubKey : ", pubAddr, mpcAddress) 30 | if err != nil || pubAddr != mpcAddress { 31 | return fmt.Errorf("mpc address %v and public key address %v is not match", mpcAddress, pubAddr) 32 | } 33 | return nil 34 | } 35 | 36 | // PublicKeyToAddress impl 37 | func (b *Bridge) PublicKeyToAddress(pubKeyHex string) (string, error) { 38 | return PublicKeyToAddress(pubKeyHex) 39 | } 40 | 41 | func PublicKeyToAddress(pubKeyHex string) (string, error) { 42 | pubKey := pubKeyHex 43 | if common.HasHexPrefix(pubKey) { 44 | pubKey = pubKey[2:] 45 | } 46 | pub := common.FromHex(pubKey) 47 | if len(pub) == ed25519.PublicKeySize+1 && pub[0] == 0xED { 48 | return types.PublicKeyFromBytes((pub[1:])).String(), nil 49 | } 50 | if len(pub) == ed25519.PublicKeySize { 51 | return types.PublicKeyFromBytes(pub).String(), nil 52 | } 53 | return "", fmt.Errorf("pubKeyHex format error : %v", pubKeyHex) 54 | } 55 | -------------------------------------------------------------------------------- /tokens/cardano/tools/newWallet/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/log" 8 | "github.com/cosmos/go-bip39" 9 | "github.com/echovl/cardano-go" 10 | "github.com/echovl/cardano-go/crypto" 11 | ) 12 | 13 | var ( 14 | paramNetwork string 15 | ) 16 | 17 | const ( 18 | entropySizeInBits = 160 19 | purposeIndex uint32 = 1852 + 0x80000000 20 | coinTypeIndex uint32 = 1815 + 0x80000000 21 | accountIndex uint32 = 0x80000000 22 | externalChainIndex uint32 = 0x0 23 | ) 24 | 25 | func initFlags() { 26 | flag.StringVar(¶mNetwork, "p", "", "network, eg. mainnet, testnet, etc.") 27 | 28 | flag.Parse() 29 | } 30 | 31 | func main() { 32 | log.SetLogger(6, false, true) 33 | 34 | initFlags() 35 | 36 | network := cardano.Mainnet 37 | if paramNetwork != "mainnet" { 38 | network = cardano.Testnet 39 | } 40 | 41 | entropy, _ := bip39.NewEntropy(entropySizeInBits) 42 | mnemonic, _ := bip39.NewMnemonic(entropy) 43 | fmt.Println("mnemonic", mnemonic) 44 | rootKey := crypto.NewXPrvKeyFromEntropy(entropy, "") 45 | accountKey := rootKey.Derive(purposeIndex). 46 | Derive(coinTypeIndex). 47 | Derive(accountIndex) 48 | chainKey := accountKey.Derive(externalChainIndex) 49 | stakeKey := accountKey.Derive(2).Derive(0) 50 | addr0Key := chainKey.Derive(0) 51 | 52 | payment, err := cardano.NewKeyCredential(addr0Key.PubKey()) 53 | if err != nil { 54 | panic(err) 55 | } 56 | enterpriseAddr, err := cardano.NewEnterpriseAddress(network, payment) 57 | if err != nil { 58 | panic(err) 59 | } 60 | fmt.Println("addr", enterpriseAddr.String()) 61 | 62 | fmt.Println("private key", addr0Key.PrvKey().Bech32("addr_sk")) 63 | fmt.Println("public key", stakeKey.PrvKey().Bech32("addr_vk")) 64 | } 65 | -------------------------------------------------------------------------------- /tokens/reef/tools/swapin/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/log" 7 | "github.com/anyswap/CrossChain-Router/v3/mpc" 8 | "github.com/anyswap/CrossChain-Router/v3/params" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens" 10 | "github.com/anyswap/CrossChain-Router/v3/tokens/reef" 11 | ) 12 | 13 | var ( 14 | bridge = reef.NewCrossChainBridge() 15 | 16 | paramConfigFile string 17 | paramChainID string 18 | 19 | paramPublicKey string 20 | 21 | mpcConfig *mpc.Config 22 | ) 23 | 24 | func initFlags() { 25 | flag.StringVar(¶mConfigFile, "config", "", "config file to init mpc and gateway") 26 | flag.StringVar(¶mChainID, "chainID", "", "chain id") 27 | 28 | flag.StringVar(¶mPublicKey, "pubkey", "", "signer public key") 29 | 30 | flag.Parse() 31 | } 32 | 33 | func main() { 34 | log.SetLogger(6, false, true) 35 | initAll() 36 | 37 | } 38 | 39 | func initAll() { 40 | initFlags() 41 | initConfig() 42 | initBridge() 43 | } 44 | func initConfig() { 45 | config := params.LoadRouterConfig(paramConfigFile, true, false) 46 | if config.FastMPC != nil { 47 | mpcConfig = mpc.InitConfig(config.FastMPC, true) 48 | } else { 49 | mpcConfig = mpc.InitConfig(config.MPC, true) 50 | } 51 | log.Info("init config finished", "IsFastMPC", mpcConfig.IsFastMPC) 52 | } 53 | 54 | func initBridge() { 55 | cfg := params.GetRouterConfig() 56 | apiAddrs := cfg.Gateways[paramChainID] 57 | if len(apiAddrs) == 0 { 58 | log.Fatal("gateway not found for chain ID", "chainID", paramChainID) 59 | } 60 | apiAddrsExt := cfg.GatewaysExt[paramChainID] 61 | bridge.SetGatewayConfig(&tokens.GatewayConfig{ 62 | APIAddress: apiAddrs, 63 | APIAddressExt: apiAddrsExt, 64 | }) 65 | log.Info("init bridge finished") 66 | } 67 | -------------------------------------------------------------------------------- /tokens/flow/transaction/CreateAccount.cdc: -------------------------------------------------------------------------------- 1 | import FungibleToken from 0x9a0766d93b6608b7 2 | import FlowToken from 0x7e60df042a9c0868 3 | transaction(pubKey:String) { 4 | let vaultRef: &FlowToken.Vault 5 | let vaultStoragePath: StoragePath 6 | let vaultPublicPath:PublicPath 7 | let receiverRef:Capability<&{FungibleToken.Receiver}> 8 | let publicKey:PublicKey 9 | let hashAlgorithm:HashAlgorithm 10 | let weight:UFix64 11 | let deposit:UFix64 12 | let account:AuthAccount 13 | prepare(acct: AuthAccount) { 14 | self.vaultStoragePath= /storage/flowTokenVault 15 | self.vaultPublicPath= /public/flowTokenReceiver 16 | self.publicKey=PublicKey( 17 | publicKey: pubKey.decodeHex(), 18 | signatureAlgorithm: SignatureAlgorithm.ECDSA_secp256k1 19 | ) 20 | self.hashAlgorithm=HashAlgorithm.SHA3_256 21 | self.weight=1000.0 22 | self.deposit=100.0 23 | self.account = AuthAccount(payer: acct) 24 | 25 | self.account.keys.add(publicKey:self.publicKey , hashAlgorithm: self.hashAlgorithm, weight: self.weight) 26 | 27 | self.vaultRef = acct.borrow<&FlowToken.Vault>(from: self.vaultStoragePath) 28 | ?? panic("Could not borrow a reference to the owner's vault") 29 | let recipient=getAccount(self.account.address) 30 | self.receiverRef = recipient.getCapability<&{FungibleToken.Receiver}>(self.vaultPublicPath) 31 | } 32 | 33 | execute { 34 | let temporaryVault <- self.vaultRef.withdraw(amount: self.deposit) 35 | let receiver=self.receiverRef.borrow()??panic("get receiver for capability fails") 36 | receiver.deposit(from:<-temporaryVault) 37 | log("account:".concat(self.account.address.toString())) 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /tokens/cardano/address.go: -------------------------------------------------------------------------------- 1 | package cardano 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/common" 8 | "github.com/btcsuite/btcutil/bech32" 9 | cardanosdk "github.com/echovl/cardano-go" 10 | "github.com/echovl/cardano-go/crypto" 11 | ) 12 | 13 | // IsValidAddress check address 14 | func (b *Bridge) IsValidAddress(addr string) bool { 15 | if _, err := cardanosdk.NewAddress(addr); err != nil { 16 | return false 17 | } 18 | return true 19 | } 20 | 21 | // PublicKeyToAddress impl 22 | func (b *Bridge) PublicKeyToAddress(pubKeyHex string) (string, error) { 23 | pubStr, err := bech32.EncodeFromBase256("addr_vk", common.FromHex(pubKeyHex)) 24 | if err != nil { 25 | return "", err 26 | } 27 | pubKey, err := crypto.NewPubKey(pubStr) 28 | if err != nil { 29 | return "", err 30 | } 31 | if pubKeyHex != pubKey.String() && pubKeyHex != "0x"+pubKey.String() { 32 | return "", errors.New("pubKey not match") 33 | } 34 | payment, err := cardanosdk.NewKeyCredential(pubKey) 35 | if err != nil { 36 | return "", err 37 | } 38 | network := cardanosdk.Mainnet 39 | if b.GetChainConfig().GetChainID().Cmp(GetStubChainID(testnetNetWork)) == 0 { 40 | network = cardanosdk.Testnet 41 | } 42 | enterpriseAddr, err := cardanosdk.NewEnterpriseAddress(network, payment) 43 | if err != nil { 44 | return "", err 45 | } 46 | return enterpriseAddr.String(), nil 47 | } 48 | 49 | // VerifyMPCPubKey verify mpc address and public key is matching 50 | func (b *Bridge) VerifyMPCPubKey(mpcAddress, mpcPubkey string) error { 51 | addr, err := b.PublicKeyToAddress(mpcPubkey) 52 | if err != nil { 53 | return err 54 | } 55 | if addr == mpcAddress { 56 | return nil 57 | } 58 | return errors.New(fmt.Sprint("addr not match ", "derivedAddr", addr, "Addr", mpcAddress)) 59 | } 60 | -------------------------------------------------------------------------------- /tokens/iota/tools/sendMessage/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | "fmt" 7 | "time" 8 | 9 | "github.com/anyswap/CrossChain-Router/v3/log" 10 | iotago "github.com/iotaledger/iota.go/v2" 11 | ) 12 | 13 | var ( 14 | paramNetwork string 15 | paramIndex string 16 | paramData string 17 | ) 18 | 19 | func initFlags() { 20 | flag.StringVar(¶mNetwork, "p", "", "network url") 21 | flag.StringVar(¶mIndex, "index", "", "payload index") 22 | flag.StringVar(¶mData, "data", "", "payload data") 23 | flag.Parse() 24 | } 25 | 26 | func main() { 27 | log.SetLogger(6, false, true) 28 | 29 | initFlags() 30 | 31 | // create a new node API client 32 | nodeHTTPAPIClient := iotago.NewNodeHTTPAPIClient(paramNetwork) 33 | ctx, cancelFunc := context.WithTimeout(context.Background(), 15*time.Second) 34 | defer cancelFunc() 35 | 36 | // fetch the node's info to know the min. required PoW score 37 | if info, err := nodeHTTPAPIClient.Info(ctx); err != nil { 38 | log.Fatal("Info", "paramNetwork", paramNetwork, "err", err) 39 | } else { 40 | fmt.Printf("info: %+v\n", info) 41 | 42 | // craft an indexation payload 43 | indexationPayload := &iotago.Indexation{ 44 | Index: []byte(paramIndex), 45 | Data: []byte(paramData), 46 | } 47 | 48 | if message, err := iotago.NewMessageBuilder(). 49 | Payload(indexationPayload). 50 | Tips(ctx, nodeHTTPAPIClient). 51 | NetworkID(iotago.NetworkIDFromString(info.NetworkID)). 52 | ProofOfWork(ctx, info.MinPowScore). 53 | Build(); err != nil { 54 | log.Fatal("NewMessageBuilder", "err", err) 55 | } else { 56 | if res, err := nodeHTTPAPIClient.SubmitMessage(ctx, message); err != nil { 57 | log.Fatal("SubmitMessage", "err", err) 58 | } else { 59 | fmt.Printf("res: %+v\n", res) 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tokens/cardano/cardanoCmd.go: -------------------------------------------------------------------------------- 1 | package cardano 2 | 3 | import ( 4 | "math/big" 5 | ) 6 | 7 | const ( 8 | AdaAsset = "lovelace" 9 | ) 10 | 11 | var ( 12 | FixAdaAmount = big.NewInt(1500000) 13 | DefaultAdaAmount = big.NewInt(2000000) 14 | QueryTransaction = "{transactions(where: { hash: { _eq: \"%s\"}}) {block {number epochNo slotNo}hash metadata{key value} inputs(order_by:{sourceTxHash:asc}){address value} outputs(order_by:{index:asc}){address index tokens{ asset{policyId assetName}quantity}value}validContract}}" 15 | QueryOutputs = "{utxos(where: { address: { _eq: \"%s\"}}) {txHash index tokens {asset {policyId assetName} quantity} value}}" 16 | 17 | QueryTIPAndProtocolParams = "{ cardano { tip { number slotNo epoch { number protocolParams { coinsPerUtxoByte keyDeposit maxBlockBodySize maxBlockExMem maxTxSize maxValSize minFeeA minFeeB minPoolCost minUTxOValue} } } } }" 18 | 19 | TransactionChaining = &TransactionChainingMap{InputKey: UtxoKey{}, AssetsMap: make(map[string]string)} 20 | TransactionChainingKeyCache = &TransactionChainingKey{SpentUtxoMap: make(map[UtxoKey]bool), SpentUtxoListGropByTxHash: make(map[string]*[]UtxoKey)} 21 | ) 22 | 23 | func AddTransactionChainingKeyCache(txhash string, txIns *[]UtxoKey) { 24 | for _, inputKey := range *txIns { 25 | TransactionChainingKeyCache.SpentUtxoMap[inputKey] = true 26 | } 27 | TransactionChainingKeyCache.SpentUtxoListGropByTxHash[txhash] = txIns 28 | } 29 | 30 | func ClearTransactionChainingKeyCache(txhash string) { 31 | if TransactionChainingKeyCache.SpentUtxoListGropByTxHash[txhash] != nil { 32 | list := TransactionChainingKeyCache.SpentUtxoListGropByTxHash[txhash] 33 | for _, key := range *list { 34 | delete(TransactionChainingKeyCache.SpentUtxoMap, key) 35 | } 36 | delete(TransactionChainingKeyCache.SpentUtxoListGropByTxHash, txhash) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /leveldb/database.go: -------------------------------------------------------------------------------- 1 | package leveldb 2 | 3 | import "io" 4 | 5 | // KeyValueReader wraps the Has and Get method of a backing data store. 6 | type KeyValueReader interface { 7 | // Has retrieves if a key is present in the key-value data store. 8 | Has(key []byte) (bool, error) 9 | 10 | // Get retrieves the given key if it's present in the key-value data store. 11 | Get(key []byte) ([]byte, error) 12 | } 13 | 14 | // KeyValueWriter wraps the Put method of a backing data store. 15 | type KeyValueWriter interface { 16 | // Put inserts the given value into the key-value data store. 17 | Put(key []byte, value []byte) error 18 | 19 | // Delete removes the key from the key-value data store. 20 | Delete(key []byte) error 21 | } 22 | 23 | // Stater wraps the Stat method of a backing data store. 24 | type Stater interface { 25 | // Stat returns a particular internal stat of the database. 26 | Stat(property string) (string, error) 27 | } 28 | 29 | // Compacter wraps the Compact method of a backing data store. 30 | type Compacter interface { 31 | // Compact flattens the underlying data store for the given key range. In essence, 32 | // deleted and overwritten versions are discarded, and the data is rearranged to 33 | // reduce the cost of operations needed to access them. 34 | // 35 | // A nil start is treated as a key before all keys in the data store; a nil limit 36 | // is treated as a key after all keys in the data store. If both is nil then it 37 | // will compact entire data store. 38 | Compact(start []byte, limit []byte) error 39 | } 40 | 41 | // KeyValueStore contains all the methods required to allow handling different 42 | // key-value data stores backing the high level database. 43 | type KeyValueStore interface { 44 | KeyValueReader 45 | KeyValueWriter 46 | Batcher 47 | Iteratee 48 | Stater 49 | Compacter 50 | io.Closer 51 | } 52 | -------------------------------------------------------------------------------- /tokens/stellar/README.md: -------------------------------------------------------------------------------- 1 | # stellar router specials 2 | 3 | ## stellar token config ContractAddress item 4 | 5 | `ContractAddress` is `native`(XLM) or format of `Code/Issuser` 6 | 7 | `XLM` stands for native 8 | 9 | ## stellar chain and token config RouterContract item 10 | 11 | `RouterContract` is the `mpc` address 12 | 13 | ## stellar public key to stellar address 14 | 15 | ```shell 16 | go run ./tokens/stellar/tools/publicKeyToAddress/main.go -p 0xED146f71db711bc259176f9bcba1756308d2a7af0f1c0b90deece65997a84c8f56 17 | # output 18 | address: GAKG64O3OEN4EWIXN6N4XILVMMENFJ5PB4OAXEG65TTFTF5IJSHVMBIC 19 | ``` 20 | 21 | ## router mechanism 22 | 23 | user send asset to `mpc` address with memo of the following format 24 | 25 | ``` 26 | len(hexBytesArray(bindAddress)) hexBytesArray(bindAddress) zeroPadding(hexBytesArray(toChainID)) 27 | 28 | example: 29 | 30 | bindAddress: 0xC5107334A3Ae117E3DaD3570b419618C905Aa5eC toChainID:5777 31 | 32 | [20 197 16 115 52 163 174 17 126 61 173 53 112 180 25 97 140 144 90 165 236 0 0 0 0 0 0 0 0 0 87 119] 33 | 34 | output: 35 | 14c5107334a3ae117e3dad3570b419618c905aa5ec0000000000000000001691 36 | ``` 37 | 38 | to specify route asset to which address (`bindAddress`) 39 | and to which destination blockchain (`toChainID`) 40 | 41 | ## stellar tools 42 | 43 | use `-h` option to get help info for each tool 44 | 45 | example: 46 | 47 | ```shell 48 | go run tokens/stellar/tools/publicKeyToAddress/main.go -h 49 | ``` 50 | 51 | ```text 52 | addressToPublickey 53 | convert stellar address to stellar public key(ed25519) 54 | publicKeyToAddress 55 | convert stellar public key to stellar address 56 | buildSwapMemo 57 | format swapout memo by toAddress and toChainID 58 | sendPaymentTx 59 | send mpc signed Payment tx 60 | sendTrustLineTx 61 | send mpc signed TrustLine tx 62 | getStubChainID 63 | get stellar chainID 64 | ``` 65 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/scalarmult.go: -------------------------------------------------------------------------------- 1 | package tweetnacl 2 | 3 | /* 4 | #include "tweetnacl.h" 5 | */ 6 | import "C" 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // The number of bytes in the group element component of scalar multiplication. 13 | const SCALARMULT_BYTES int = 32 14 | 15 | // The number of bytes in the integer component of scalar multiplication. 16 | const SCALARMULT_SCALARBYTES int = 32 17 | 18 | // Wrapper function for crypto_scalarmult_base. 19 | // 20 | // Computes the scalar product of a standard group element and an integer n. 21 | // 22 | // Ref. http://nacl.cr.yp.to/scalarmult.html 23 | func ScalarMultBase(n []byte) ([]byte, error) { 24 | if len(n) != SCALARMULT_SCALARBYTES { 25 | return nil, fmt.Errorf("Error calculating base scalar product (%v)", "invalid integer") 26 | } 27 | 28 | q := make([]byte, SCALARMULT_BYTES) 29 | rc := C.crypto_scalarmult_base(makePtr(q), makePtr(n)) 30 | 31 | if rc == 0 { 32 | return q, nil 33 | } 34 | 35 | return nil, fmt.Errorf("Error calculating base scalar scalar product (%v)", rc) 36 | } 37 | 38 | // Wrapper function for crypto_scalarmult. 39 | // 40 | // Computes the scalar product of a group element p and an integer n. 41 | // 42 | // Ref. http://nacl.cr.yp.to/scalarmult.html 43 | func ScalarMult(n, p []byte) ([]byte, error) { 44 | if len(n) != SCALARMULT_SCALARBYTES { 45 | return nil, fmt.Errorf("Error calculating scalar product (%v)", "invalid integer") 46 | } 47 | 48 | if len(p) != SCALARMULT_BYTES { 49 | return nil, fmt.Errorf("Error calculating scalar product (%v)", "invalid group element") 50 | } 51 | 52 | q := make([]byte, SCALARMULT_BYTES) 53 | rc := C.crypto_scalarmult(makePtr(q), makePtr(n), makePtr(p)) 54 | 55 | if rc == 0 { 56 | return q, nil 57 | } 58 | 59 | return nil, fmt.Errorf("Error calculating scalar multiplication (error code %v)", rc) 60 | } 61 | -------------------------------------------------------------------------------- /tokens/reef/tools/swapout/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/log" 7 | "github.com/anyswap/CrossChain-Router/v3/mpc" 8 | "github.com/anyswap/CrossChain-Router/v3/params" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens" 10 | "github.com/anyswap/CrossChain-Router/v3/tokens/reef" 11 | ) 12 | 13 | var ( 14 | bridge = reef.NewCrossChainBridge() 15 | 16 | paramConfigFile string 17 | paramChainID string 18 | 19 | paramPublicKey string 20 | paramPrivateKey string 21 | 22 | mpcConfig *mpc.Config 23 | ) 24 | 25 | func initFlags() { 26 | flag.StringVar(¶mConfigFile, "config", "", "config file to init mpc and gateway") 27 | flag.StringVar(¶mChainID, "chainID", "", "chain id") 28 | 29 | flag.StringVar(¶mPublicKey, "pubkey", "", "signer public key") 30 | flag.StringVar(¶mPrivateKey, "prikey", "", "signer private key") 31 | 32 | flag.Parse() 33 | } 34 | 35 | func main() { 36 | log.SetLogger(6, false, true) 37 | initAll() 38 | 39 | } 40 | 41 | func initAll() { 42 | initFlags() 43 | initConfig() 44 | initBridge() 45 | } 46 | func initConfig() { 47 | config := params.LoadRouterConfig(paramConfigFile, true, false) 48 | if config.FastMPC != nil { 49 | mpcConfig = mpc.InitConfig(config.FastMPC, true) 50 | } else { 51 | mpcConfig = mpc.InitConfig(config.MPC, true) 52 | } 53 | log.Info("init config finished", "IsFastMPC", mpcConfig.IsFastMPC) 54 | } 55 | 56 | func initBridge() { 57 | cfg := params.GetRouterConfig() 58 | apiAddrs := cfg.Gateways[paramChainID] 59 | if len(apiAddrs) == 0 { 60 | log.Fatal("gateway not found for chain ID", "chainID", paramChainID) 61 | } 62 | apiAddrsExt := cfg.GatewaysExt[paramChainID] 63 | bridge.SetGatewayConfig(&tokens.GatewayConfig{ 64 | APIAddress: apiAddrs, 65 | APIAddressExt: apiAddrsExt, 66 | }) 67 | log.Info("init bridge finished") 68 | } 69 | -------------------------------------------------------------------------------- /tokens/btc/rpcclient.go: -------------------------------------------------------------------------------- 1 | package btc 2 | 3 | import ( 4 | "sort" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/rpc/client" 7 | ) 8 | 9 | // PostTransaction call post to /tx 10 | func PostTransaction(url, txHex string) (txHash string, err error) { 11 | restApi := url + "/tx" 12 | txHash, err = client.RPCRawPost(restApi, txHex) 13 | if err == nil { 14 | return txHash, nil 15 | } 16 | return "", err 17 | } 18 | 19 | // GetTransactionByHash get tx by hash 20 | func GetTransactionByHash(url, txHash string) (*ElectTx, error) { 21 | var result ElectTx 22 | var err error 23 | restApi := url + "/tx/" + txHash 24 | err = client.RPCGet(&result, restApi) 25 | if err == nil { 26 | return &result, nil 27 | } 28 | return nil, err 29 | } 30 | 31 | func EstimateFeePerKb(url string, blocks int) (fee int64, err error) { 32 | var result map[int]float64 33 | restApi := url + "/fee-estimates" 34 | err = client.RPCGet(&result, restApi) 35 | if err != nil { 36 | return 0, err 37 | } 38 | return int64(result[blocks] * 1000), nil 39 | } 40 | 41 | func FindUtxos(url string, addr string) (result []*ElectUtxo, err error) { 42 | restApi := url + "/address/" + addr + "/utxo" 43 | err = client.RPCGet(&result, restApi) 44 | if err == nil { 45 | sort.Sort(SortableElectUtxoSlice(result)) 46 | return result, nil 47 | } 48 | return nil, err 49 | } 50 | 51 | // GetElectTransactionStatus call /tx/{txHash}/status 52 | func GetElectTransactionStatus(url, txHash string) (result *ElectTxStatus, err error) { 53 | restApi := url + "/tx/" + txHash + "/status" 54 | err = client.RPCGet(&result, restApi) 55 | if err == nil { 56 | return result, nil 57 | } 58 | return nil, err 59 | } 60 | 61 | func GetLatestBlockNumber(url string) (result uint64, err error) { 62 | restApi := url + "/blocks/tip/height" 63 | err = client.RPCGet(&result, restApi) 64 | if err == nil { 65 | return result, nil 66 | } 67 | return 0, err 68 | } 69 | -------------------------------------------------------------------------------- /tokens/ripple/README.md: -------------------------------------------------------------------------------- 1 | # ripple router specials 2 | 3 | ## ripple token config ContractAddress item 4 | 5 | `ContractAddress` is `XRP` or format of `Currency/Issuser` 6 | 7 | `XRP` stands for native 8 | 9 | ## ripple chain and token config RouterContract item 10 | 11 | `RouterContract` is the `mpc` address 12 | 13 | ## ripple public key to ripple address 14 | 15 | ```shell 16 | go run tokens/ripple/tools/publicKeyToAddress/main.go 04b4904f8a2ea01891678fec45c63fb1f221666e7d19cfeeb28f08a6d99cac91cbc12731f4c144aef501e34a6eaa0b5418ed5d138b192964bc5ccf4cde67246ca3 17 | # output 18 | address: rDsvn6aJG4YMQdHnuJtP9NLrFp18JYTJUf 19 | ``` 20 | 21 | ## router mechanism 22 | 23 | 1. Swapout from ripple to other chain 24 | 25 | user send asset to `mpc` address with memo of the following format 26 | 27 | ``` 28 | bindAddress:toChainID 29 | 30 | example: 31 | 32 | 0x1111111111111111111111111111111111111111:4 33 | ``` 34 | 35 | to specify route asset to which address (`bindAddress`) 36 | and to which destination blockchain (`toChainID`) 37 | 38 | 39 | 2. Swapin from other chain to ripple 40 | 41 | ```solidity 42 | function anySwapOut(address token, string memory to, uint amount, uint toChainID) 43 | ``` 44 | 45 | `to` is the destination on ripple, it can be an ripple address, or `ripple_address:destinationTag` for some address that require destination tag. 46 | 47 | 48 | ## ripple tools 49 | 50 | use `-h` option to get help info for each tool 51 | 52 | example: 53 | 54 | ```shell 55 | go run tokens/ripple/tools/publicKeyToAddress/main.go -h 56 | ``` 57 | 58 | for transaction flags, please refer `tokens/ripple/rubblelabs/ripple/data/flags.go` 59 | 60 | ```text 61 | publicKeyToAddress 62 | convert ripple public key to ripple address 63 | 64 | sendPaymentTx 65 | send mpc signed Payment tx 66 | 67 | sendAccountSetTx 68 | send mpc signed AccountSet tx 69 | 70 | sendTrustSetTx 71 | send mpc signed TrustSet tx 72 | ``` 73 | -------------------------------------------------------------------------------- /tools/rlp/decode_tail_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The go-ethereum Authors 2 | // This file is part of the go-ethereum library. 3 | // 4 | // The go-ethereum library is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Lesser General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // The go-ethereum library is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with the go-ethereum library. If not, see . 16 | 17 | package rlp 18 | 19 | import ( 20 | "bytes" 21 | "fmt" 22 | ) 23 | 24 | type structWithTail struct { 25 | A, B uint 26 | C []uint `rlp:"tail"` 27 | } 28 | 29 | func ExampleDecode_structTagTail() { 30 | // In this example, the "tail" struct tag is used to decode lists of 31 | // differing length into a struct. 32 | var val structWithTail 33 | 34 | err := Decode(bytes.NewReader([]byte{0xC4, 0x01, 0x02, 0x03, 0x04}), &val) 35 | fmt.Printf("with 4 elements: err=%v val=%v\n", err, val) 36 | 37 | err = Decode(bytes.NewReader([]byte{0xC6, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}), &val) 38 | fmt.Printf("with 6 elements: err=%v val=%v\n", err, val) 39 | 40 | // Note that at least two list elements must be present to 41 | // fill fields A and B: 42 | err = Decode(bytes.NewReader([]byte{0xC1, 0x01}), &val) 43 | fmt.Printf("with 1 element: err=%q\n", err) 44 | 45 | // Output: 46 | // with 4 elements: err= val={1 2 [3 4]} 47 | // with 6 elements: err= val={1 2 [3 4 5 6]} 48 | // with 1 element: err="rlp: too few elements for rlp.structWithTail" 49 | } 50 | -------------------------------------------------------------------------------- /worker/utils.go: -------------------------------------------------------------------------------- 1 | package worker 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/log" 7 | ) 8 | 9 | var ( 10 | maxTxNotFoundTime = int64(3 * 24 * 3600) 11 | 12 | maxVerifyLifetime = int64(7 * 24 * 3600) 13 | restIntervalInVerifyJob = 3 * time.Second 14 | 15 | maxDoSwapLifetime = int64(7 * 24 * 3600) 16 | restIntervalInDoSwapJob = 10 * time.Second 17 | 18 | maxStableLifetime = int64(7 * 24 * 3600) 19 | restIntervalInStableJob = 10 * time.Second 20 | 21 | maxReplaceSwapLifetime = int64(7 * 24 * 3600) 22 | restIntervalInReplaceSwapJob = 60 * time.Second 23 | 24 | maxPassBigValueLifetime = int64(7 * 24 * 3600) 25 | restIntervalInPassBigValJob = 300 * time.Second 26 | passBigValueTimeRequired = int64(12 * 3600) // seconds 27 | 28 | maxCheckFailedSwapLifetime = int64(2 * 24 * 3600) 29 | restIntervalInCheckFailedSwapJob = 60 * time.Second 30 | ) 31 | 32 | func now() int64 { 33 | return time.Now().Unix() 34 | } 35 | 36 | func logWorker(job, subject string, context ...interface{}) { 37 | log.Info("["+job+"] "+subject, context...) 38 | } 39 | 40 | func logWorkerError(job, subject string, err error, context ...interface{}) { 41 | fields := []interface{}{"err", err} 42 | fields = append(fields, context...) 43 | log.Error("["+job+"] "+subject, fields...) 44 | } 45 | 46 | func logWorkerWarn(job, subject string, context ...interface{}) { 47 | log.Warn("["+job+"] "+subject, context...) 48 | } 49 | 50 | func logWorkerTrace(job, subject string, context ...interface{}) { 51 | log.Trace("["+job+"] "+subject, context...) 52 | } 53 | 54 | func getSepTimeInFind(dist int64) int64 { 55 | nowTime := now() 56 | if nowTime > dist { 57 | return nowTime - dist 58 | } 59 | return 0 60 | } 61 | 62 | func restInJob(duration time.Duration) { 63 | time.Sleep(duration) 64 | } 65 | 66 | func sleepSeconds(secs int) { 67 | time.Sleep(time.Duration(secs) * time.Second) 68 | } 69 | -------------------------------------------------------------------------------- /worker/aggregate.go: -------------------------------------------------------------------------------- 1 | package worker 2 | 3 | import ( 4 | "errors" 5 | "time" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/cmd/utils" 8 | "github.com/anyswap/CrossChain-Router/v3/log" 9 | "github.com/anyswap/CrossChain-Router/v3/mongodb" 10 | "github.com/anyswap/CrossChain-Router/v3/tokens" 11 | "github.com/anyswap/CrossChain-Router/v3/tokens/cardano" 12 | ) 13 | 14 | var ( 15 | aggInterval = 7 * 24 * time.Hour 16 | 17 | errInvalidAggregate = errors.New("invalid agregate") 18 | ) 19 | 20 | func verifyAggregate(msgHash []string, args *tokens.BuildTxArgs) error { 21 | if args.FromChainID == nil || args.ToChainID == nil || 22 | args.FromChainID.Cmp(args.ToChainID) != 0 { 23 | return errors.New("aggregate: from and to chainid is not same") 24 | } 25 | if cardano.BridgeInstance == nil || 26 | !cardano.SupportsChainID(args.ToChainID) { 27 | return errors.New("aggregate: dest chain does not support it") 28 | } 29 | return cardano.BridgeInstance.VerifyAggregate(msgHash, args) 30 | } 31 | 32 | // StartAggregateJob aggregate job 33 | func StartAggregateJob() { 34 | logWorker("aggregate", "start router aggregate job") 35 | if cardano.BridgeInstance == nil { 36 | return 37 | } 38 | mongodb.MgoWaitGroup.Add(1) 39 | go DoAggregateJob() 40 | log.Warnf("StartAggregateJob end:%+v", time.Now()) 41 | } 42 | 43 | func DoAggregateJob() { 44 | defer mongodb.MgoWaitGroup.Done() 45 | for { 46 | if utils.IsCleanuping() { 47 | return 48 | } 49 | logWorker("aggregate", "start aggregate job") 50 | doAggregateJob() 51 | logWorker("aggregate", "finish aggregate job") 52 | time.Sleep(aggInterval) 53 | } 54 | 55 | } 56 | 57 | func doAggregateJob() { 58 | if utils.IsCleanuping() { 59 | return 60 | } 61 | if txHash, err := cardano.BridgeInstance.AggregateTx(); err != nil { 62 | logWorkerError("aggregate", "aggregate tx err", err) 63 | } else { 64 | logWorker("aggregate", "aggregate tx success txHash:", txHash) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/crypto_verify.go: -------------------------------------------------------------------------------- 1 | package tweetnacl 2 | 3 | /* 4 | #include "tweetnacl.h" 5 | */ 6 | import "C" 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // The number of bytes in a 'secret' for the crypto_verify_16 function. 13 | const VERIFY16_BYTES int = 16 14 | 15 | // The number of bytes in a 'secret' for the crypto_verify_32 function. 16 | const VERIFY32_BYTES int = 32 17 | 18 | // Wrapper function for crypto_verify_16. 19 | // 20 | // Compares two 'secrets' encoded as 16 byte arrays in a time independent 21 | // of the content of the arrays. 22 | // 23 | // Ref. http://nacl.cr.yp.to/verify.html 24 | func CryptoVerify16(x, y []byte) (bool, error) { 25 | if len(x) != VERIFY16_BYTES { 26 | return false, fmt.Errorf("Error verifying 16 byte arrays (%v)", "invalid X") 27 | } 28 | 29 | if len(y) != VERIFY16_BYTES { 30 | return false, fmt.Errorf("Error verifying 16 byte arrays (%v)", "invalid Y") 31 | } 32 | 33 | rc := C.crypto_verify_16(makePtr(x), makePtr(y)) 34 | 35 | if rc == 0 { 36 | return true, nil 37 | } 38 | 39 | if rc == -1 { 40 | return false, nil 41 | } 42 | 43 | return false, fmt.Errorf("Error verifying 16 byte arrays (%v)", rc) 44 | } 45 | 46 | // Wrapper function for crypto_verify_32. 47 | // 48 | // Compares two 'secrets' encoded as 32 byte arrays in a time independent 49 | // of the content of the arrays. 50 | // 51 | // Ref. http://nacl.cr.yp.to/verify.html 52 | func CryptoVerify32(x, y []byte) (bool, error) { 53 | if len(x) != VERIFY32_BYTES { 54 | return false, fmt.Errorf("Error verifying 32 byte arrays (%v)", "invalid X") 55 | } 56 | 57 | if len(y) != VERIFY32_BYTES { 58 | return false, fmt.Errorf("Error verifying 32 byte arrays (%v)", "invalid Y") 59 | } 60 | 61 | rc := C.crypto_verify_32(makePtr(x), makePtr(y)) 62 | 63 | if rc == 0 { 64 | return true, nil 65 | } 66 | 67 | if rc == -1 { 68 | return false, nil 69 | } 70 | 71 | return false, fmt.Errorf("Error verifying 32 byte arrays (%v)", rc) 72 | } 73 | -------------------------------------------------------------------------------- /tokens/stellar/bridge_test.go: -------------------------------------------------------------------------------- 1 | //go:build ignore 2 | 3 | package stellar 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/anyswap/CrossChain-Router/v3/tokens" 9 | ) 10 | 11 | func PrepareTestBridge() *Bridge { 12 | bridge := NewCrossChainBridge("1000005786703") 13 | bridge.SetGatewayConfig(&tokens.GatewayConfig{ 14 | APIAddress: []string{"https://horizon-testnet.stellar.org"}, 15 | }) 16 | bridge.InitRemotes() 17 | return bridge 18 | } 19 | 20 | func TestGetFee(t *testing.T) { 21 | bridge := PrepareTestBridge() 22 | if ans := bridge.GetFee(); ans == 0 { 23 | t.Fatalf("GetFee expected >0 , but got %v", ans) 24 | } 25 | } 26 | 27 | func TestGetAccount(t *testing.T) { 28 | bridget := PrepareTestBridge() 29 | if _, err := bridget.GetAccount("GC4Y6G2KHMKOVTQLVBKF4MDAXX2BWOYBRLZWQ2H6POLTVOLMWTMDP7BE"); err != nil { 30 | t.Fatalf("GetAccount expected not err, but got %v", err) 31 | } 32 | } 33 | 34 | func TestGetLatestBlockNumber(t *testing.T) { 35 | bridge := PrepareTestBridge() 36 | if num, err := bridge.GetLatestBlockNumber(); num == 0 || err != nil { 37 | t.Fatalf("GetLatestBlockNumber expected not err, but got %v %v", num, err) 38 | } 39 | } 40 | 41 | func TestGetTx(t *testing.T) { 42 | bridge := PrepareTestBridge() 43 | if _, err := bridge.GetTransaction("6fc1c449b740fd937b435e8414c1892fe9e5c5aacded3b4ca4ba0e5519862588"); err != nil { 44 | t.Fatalf("GetTx expected not err, but got %v", err) 45 | } 46 | } 47 | 48 | func TestGetAccountBalance(t *testing.T) { 49 | bridget := PrepareTestBridge() 50 | if _, err := bridget.GetBalance("GC4Y6G2KHMKOVTQLVBKF4MDAXX2BWOYBRLZWQ2H6POLTVOLMWTMDP7BE"); err != nil { 51 | t.Fatalf("TestGetAccountBalance expected not err, but got %v", err) 52 | } 53 | } 54 | 55 | func TestGetAsset(t *testing.T) { 56 | bridget := PrepareTestBridge() 57 | if _, err := bridget.GetAsset("ZUSD", "GACP35XDWYIP6IS5IL22CHOZKJOXICQIK4CFJ65Q4O2IIUNTKUGZY2KI"); err != nil { 58 | t.Fatalf("GetAsset expected not err, but got %v", err) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tokens/reef/README_deployment.md: -------------------------------------------------------------------------------- 1 | # Reef router deploy instructions 2 | 3 | ## Network 4 | Make sure the rpc endpoint could be connected 5 | | Env | Rpc Endpoint | Graphql | 6 | | ---- | ---- | ---- | 7 | | Mainnet | https://rpc.reefscan.com | wss://reefscan.com/graphql | 8 | | Testnet | https://rpc-testnet.reefscan.com | wss://testnet.reefscan.com/graphql | 9 | 10 | 11 | ## Setup Reef contract 12 | ### a. run the lastest mpc node 13 | - use mpc `support-sr25519` to generate a new mpc public key base on sr25519 14 | https://github.com/anyswap/FastMulThreshold-DSA/tree/support-sr25519 15 | 16 | ``` 17 | ./gsmpc-test-2-2.sh $(pwd) 5871 "" SR25519 18 | ``` 19 | 20 | ### b. create mpc account 21 | - get reef address (mpc SS58 Address) 22 | ``` 23 | go run tokens/reef/tools/getReefAddress/main.go -h 24 | ``` 25 | - get some native token `REEF` to mpc address, airdrop for testnet 26 | https://app.element.io/#/room/#reef:matrix.org 27 | 28 | - git clone `https://github.com/anyswap/Router-Demo-JS/tree/reef` and setup js env 29 | ``` 30 | npm install -g yarn 31 | yarn i 32 | ``` 33 | 34 | - random a evm private key(mpc EVM address) to bind reef address 35 | 36 | - use `bindEvmaddr` tools to bind evm address 37 | ``` 38 | go run tokens/reef/tools/bindEvmaddr/main.go -h 39 | ``` 40 | 41 | ### c. contract deploy 42 | - perpare a deploying account which contains `REEF` 43 | - use https://github.com/reef-defi/hardhat-reef to deploy 44 | - the mpc address is gotten above(mpc EVM address) 45 | 46 | ## Setup CrossChain-Router 47 | ### a.setup reef config 48 | 49 | ``` 50 | [Gateways] 51 | 1001380271430 = ["https://rpc.reefscan.com/"] 52 | 1001380271431 = ["https://rpc-testnet.reefscan.com/"] 53 | 54 | [Extra.Customs.1001380271430] 55 | ws = "wss://reefscan.com/graphql,wss://reefscan.com/graphql" 56 | jspath = "/Router-Demo-JS/reef" 57 | 58 | [Extra.Customs.1001380271431] 59 | ws = "wss://testnet.reefscan.com/graphql,wss://testnet.reefscan.com/graphql" 60 | jspath = "/Router-Demo-JS/reef" 61 | ``` -------------------------------------------------------------------------------- /tokens/tests/README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | This package is used to simplify the developing process to support `CrossChain-Router` project. 4 | 5 | It's designed to get rid of business related processes: MPC and Database. 6 | 7 | So the developers can focus on the aimed blockchain related interfaces. 8 | 9 | ## How to do tests for a new block chain 10 | 11 | 1. create a new directory to start work 12 | 13 | for example, create `tokens/tests/eth/` directory by copying from `tokens/tests/template/` 14 | 15 | change the package name accordingly after copied, and pass the building. 16 | 17 | 2. prepare test enviroment and construct a transaction to test 18 | 19 | choose or run a full node to synchronize blocks and do rpc queries. 20 | 21 | deploy smart contracts (`RouterContract` and `TokenContract`). 22 | 23 | construct and send a swapout tx by calling `RouterContract`'s function (`anySwapOut`, `anySwapOutUnderlying` or `anySwapOutNative`) 24 | 25 | 3. implement interfaces in our new directory 26 | 27 | add new source files, functions, structs, variables, and config items to implement the interfaces (verify, build, sign and send tx). 28 | 29 | for example, we can keep the `bridge.go` file concise, and do the implementations in new files. 30 | 31 | add new test module initialization in `initRouter` function in file `tokens/tests/main.go` 32 | 33 | 4. modify the config file 34 | 35 | copy the `tokens/tests/config/config-test.toml` template config file, and modify the config items. 36 | 37 | 5. testing and debuging 38 | 39 | run the test program (exit with `Ctrl+C`) 40 | 41 | ```shell 42 | go run tokens/tests/main.go -c 43 | ``` 44 | 45 | in another terminal trigger the testing 46 | 47 | ```shell 48 | # url format is "http://{host}:{port}/swap/test/{txhash}" 49 | curl -sS http://127.0.0.1:11556/swap/test/0xcea2be8a05c0155832676e89c129b785fd1e2f308439606fc5df98a0e133bff2 50 | curl -sS http://127.0.0.1:11556/swap/test/44cd067581fe9ec79699ba775d89614a013708175fb19592882b7a04c343e57e 51 | ``` 52 | -------------------------------------------------------------------------------- /tokens/stellar/tools/buildSwapMemo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/base64" 5 | "encoding/hex" 6 | "flag" 7 | "fmt" 8 | "math/big" 9 | 10 | "github.com/anyswap/CrossChain-Router/v3/common" 11 | "github.com/anyswap/CrossChain-Router/v3/log" 12 | "github.com/anyswap/CrossChain-Router/v3/tokens/stellar" 13 | ) 14 | 15 | var ( 16 | paramAddress string 17 | paramChainID string 18 | memobase64 string 19 | ) 20 | 21 | func initFlags() { 22 | flag.StringVar(¶mAddress, "a", "", "address string") 23 | flag.StringVar(¶mChainID, "c", "", "chain id string") 24 | flag.StringVar(&memobase64, "m", "", "memo base64 string") 25 | 26 | flag.Parse() 27 | } 28 | 29 | func main() { 30 | log.SetLogger(6, false, true) 31 | 32 | initFlags() 33 | 34 | chainId, ok := new(big.Int).SetString(paramChainID, 10) 35 | if !ok { 36 | log.Fatal("paramChainID format error") 37 | } 38 | 39 | if paramAddress[:2] == "0x" || paramAddress[:2] == "0X" { 40 | paramAddress = paramAddress[2:] 41 | } 42 | 43 | rtn, err := stellar.EncodeMemo(chainId, paramAddress) 44 | if err != nil { 45 | log.Fatal("genMemo error", err) 46 | } 47 | 48 | memo := hex.EncodeToString(rtn[:]) 49 | fmt.Printf("memobytes: %v\n", rtn) 50 | fmt.Printf("memo: %v\n", memo) 51 | 52 | var memobytes []byte 53 | if len(memobase64) == 0 { 54 | fmt.Printf("memo: %v \n", memo) 55 | memobytes = rtn[:] 56 | } else { 57 | fmt.Printf("memobase64: %v \n", memobase64) 58 | memobytes, err = base64.StdEncoding.DecodeString(memobase64) 59 | if err != nil || len(memobytes) == 0 { 60 | log.Fatal("parse memo error") 61 | } 62 | } 63 | fmt.Printf("memobytes: %v \n", memobytes) 64 | 65 | addrLen := int(memobytes[0]) 66 | addEnd := 1 + addrLen 67 | if len(memobytes) < addEnd+1 { 68 | log.Fatal("parse memo length error") 69 | } 70 | bindStr := common.ToHex(memobytes[1:addEnd]) 71 | bigToChainID := new(big.Int).SetBytes(memobytes[addEnd:]) 72 | fmt.Printf("bindStr: %v , toChainID: %v \n", bindStr, bigToChainID) 73 | } 74 | -------------------------------------------------------------------------------- /tokens/ripple/address.go: -------------------------------------------------------------------------------- 1 | package ripple 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "regexp" 7 | "strings" 8 | 9 | "github.com/anyswap/CrossChain-Router/v3/common" 10 | ) 11 | 12 | var rAddressReg = regexp.MustCompile(`^r[1-9a-km-zA-HJ-NP-Z]{32,33}(?::[0-9]*)?$`) 13 | 14 | // IsValidAddress check address 15 | func (b *Bridge) IsValidAddress(addr string) bool { 16 | return rAddressReg.MatchString(addr) 17 | } 18 | 19 | // GetAddressAndTag get address and tag 20 | func GetAddressAndTag(s string) (addr string, tag *uint32, err error) { 21 | if !rAddressReg.MatchString(s) { 22 | return "", nil, fmt.Errorf("invalid address '%s'", s) 23 | } 24 | parts := strings.Split(s, ":") 25 | addr = parts[0] 26 | if len(parts) == 2 { 27 | var tagVal uint32 28 | tagVal, err = common.GetUint32FromStr(parts[1]) 29 | if err != nil { 30 | return "", nil, err 31 | } 32 | tag = &tagVal 33 | return addr, tag, nil 34 | } 35 | return addr, nil, nil 36 | } 37 | 38 | // PublicKeyToAddress impl 39 | func (b *Bridge) PublicKeyToAddress(pubKeyHex string) (string, error) { 40 | return PublicKeyHexToAddress(pubKeyHex) 41 | } 42 | 43 | // PublicKeyHexToAddress convert public key hex to ripple address 44 | func PublicKeyHexToAddress(pubKeyHex string) (string, error) { 45 | pub, err := hex.DecodeString(pubKeyHex) 46 | if err != nil { 47 | return "", err 48 | } 49 | return PublicKeyToAddress(pub), nil 50 | } 51 | 52 | // PublicKeyToAddress converts pubkey to ripple address 53 | func PublicKeyToAddress(pubkey []byte) string { 54 | return GetAddress(ImportPublicKey(pubkey), nil) 55 | } 56 | 57 | // VerifyMPCPubKey verify mpc address and public key is matching 58 | func VerifyMPCPubKey(mpcAddress, mpcPubkey string) error { 59 | pubkeyAddr, err := PublicKeyHexToAddress(mpcPubkey) 60 | if err != nil { 61 | return err 62 | } 63 | if !strings.EqualFold(pubkeyAddr, mpcAddress) { 64 | return fmt.Errorf("mpc address %v and public key address %v is not match", mpcAddress, pubkeyAddr) 65 | } 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /tokens/flow/rpcclient.go: -------------------------------------------------------------------------------- 1 | package flow 2 | 3 | import ( 4 | "context" 5 | 6 | sdk "github.com/onflow/flow-go-sdk" 7 | "github.com/onflow/flow-go-sdk/access/grpc" 8 | ) 9 | 10 | var ( 11 | ctx = context.Background() 12 | ) 13 | 14 | func GetBlockNumberByHash(url string, blockId sdk.Identifier) (uint64, error) { 15 | flowClient, err := grpc.NewClient(url) 16 | if err != nil { 17 | return 0, err 18 | } 19 | latestBlock, err := flowClient.GetBlockByID(ctx, blockId) 20 | if err != nil { 21 | return 0, err 22 | } 23 | return latestBlock.Height, nil 24 | } 25 | 26 | // GetLatestBlockNumber get latest block height 27 | func GetLatestBlock(url string) (*sdk.Block, error) { 28 | flowClient, err := grpc.NewClient(url) 29 | if err != nil { 30 | return nil, err 31 | } 32 | latestBlock, err := flowClient.GetLatestBlock(ctx, true) 33 | if err != nil { 34 | return nil, err 35 | } 36 | return latestBlock, nil 37 | } 38 | 39 | // GetLatestBlockNumber get latest block height 40 | func GetAccount(url, address string) (*sdk.Account, error) { 41 | flowClient, err := grpc.NewClient(url) 42 | if err != nil { 43 | return nil, err 44 | } 45 | account, err := flowClient.GetAccount(ctx, sdk.HexToAddress(address)) 46 | if err != nil { 47 | return nil, err 48 | } 49 | return account, nil 50 | } 51 | 52 | func sendTransaction(url string, signedTx *sdk.Transaction) (string, error) { 53 | flowClient, err := grpc.NewClient(url) 54 | if err != nil { 55 | return "", err 56 | } 57 | err = flowClient.SendTransaction(ctx, *signedTx) 58 | if err != nil { 59 | return "", err 60 | } 61 | return signedTx.ID().String(), nil 62 | } 63 | 64 | // GetTransactionByHash get tx by hash 65 | func GetTransactionByHash(url, txHash string) (*sdk.TransactionResult, error) { 66 | flowClient, err := grpc.NewClient(url) 67 | if err != nil { 68 | return nil, err 69 | } 70 | result, err := flowClient.GetTransactionResult(ctx, sdk.HexToID(txHash)) 71 | if err != nil { 72 | return nil, err 73 | } 74 | return result, nil 75 | } 76 | -------------------------------------------------------------------------------- /leveldb/iterator.go: -------------------------------------------------------------------------------- 1 | package leveldb 2 | 3 | // Iterator iterates over a database's key/value pairs in ascending key order. 4 | // 5 | // When it encounters an error any seek will return false and will yield no key/ 6 | // value pairs. The error can be queried by calling the Error method. Calling 7 | // Release is still necessary. 8 | // 9 | // An iterator must be released after use, but it is not necessary to read an 10 | // iterator until exhaustion. An iterator is not safe for concurrent use, but it 11 | // is safe to use multiple iterators concurrently. 12 | type Iterator interface { 13 | // Next moves the iterator to the next key/value pair. It returns whether the 14 | // iterator is exhausted. 15 | Next() bool 16 | 17 | // Error returns any accumulated error. Exhausting all the key/value pairs 18 | // is not considered to be an error. 19 | Error() error 20 | 21 | // Key returns the key of the current key/value pair, or nil if done. The caller 22 | // should not modify the contents of the returned slice, and its contents may 23 | // change on the next call to Next. 24 | Key() []byte 25 | 26 | // Value returns the value of the current key/value pair, or nil if done. The 27 | // caller should not modify the contents of the returned slice, and its contents 28 | // may change on the next call to Next. 29 | Value() []byte 30 | 31 | // Release releases associated resources. Release should always succeed and can 32 | // be called multiple times without causing error. 33 | Release() 34 | } 35 | 36 | // Iteratee wraps the NewIterator methods of a backing data store. 37 | type Iteratee interface { 38 | // NewIterator creates a binary-alphabetical iterator over a subset 39 | // of database content with a particular key prefix, starting at a particular 40 | // initial key (or after, if it does not exist). 41 | // 42 | // Note: This method assumes that the prefix is NOT part of the start, so there's 43 | // no need for the caller to prepend the prefix to the start 44 | NewIterator(prefix []byte, start []byte) Iterator 45 | } 46 | -------------------------------------------------------------------------------- /tokens/aptos/tweetnacl/crypto_auth.go: -------------------------------------------------------------------------------- 1 | package tweetnacl 2 | 3 | /* 4 | #include "tweetnacl.h" 5 | */ 6 | import "C" 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // The number of bytes in the authenticator. 13 | const ONETIMEAUTH_BYTES int = 16 14 | 15 | // The number of bytes in the secret key used to generate the authenticator. 16 | const ONETIMEAUTH_KEYBYTES int = 32 17 | 18 | // Wrapper function for crypto_onetimeauth. 19 | // 20 | // Uses the supplied secret key to calculate an authenticator for the message. 21 | // 22 | // Ref. http://nacl.cr.yp.to/onetimeauth.html 23 | func CryptoOneTimeAuth(message, key []byte) ([]byte, error) { 24 | 25 | if len(key) != ONETIMEAUTH_KEYBYTES { 26 | return nil, fmt.Errorf("Error calculating one time authenticator (%v)", "invalid key") 27 | } 28 | 29 | authenticator := make([]byte, ONETIMEAUTH_BYTES) 30 | N := (C.ulonglong)(len(message)) 31 | 32 | rc := C.crypto_onetimeauth(makePtr(authenticator), 33 | makePtr(message), 34 | N, 35 | makePtr(key)) 36 | 37 | if rc == 0 { 38 | return authenticator, nil 39 | } 40 | 41 | return nil, fmt.Errorf("Error calculating one time authenticator (%v)", rc) 42 | } 43 | 44 | // Wrapper function for crypto_onetimeauth_verify. 45 | // 46 | // Uses the supplied secret key to verify the authenticator for the message. 47 | // 48 | // Ref. http://nacl.cr.yp.to/onetimeauth.html 49 | func CryptoOneTimeAuthVerify(authenticator, message, key []byte) (bool, error) { 50 | 51 | if len(authenticator) != ONETIMEAUTH_BYTES { 52 | return false, fmt.Errorf("Error verifying one time authenticator (%v)", "invalid authenticator") 53 | } 54 | 55 | if len(key) != ONETIMEAUTH_KEYBYTES { 56 | return false, fmt.Errorf("Error verifying one time authenticator (%v)", "invalid key") 57 | } 58 | 59 | N := (C.ulonglong)(len(message)) 60 | 61 | rc := C.crypto_onetimeauth_verify(makePtr(authenticator), 62 | makePtr(message), 63 | N, 64 | makePtr(key)) 65 | 66 | if rc == 0 { 67 | return true, nil 68 | } 69 | 70 | return false, fmt.Errorf("Error verifying one time authenticator (error code %v)", rc) 71 | } 72 | -------------------------------------------------------------------------------- /cmd/utils/utils.go: -------------------------------------------------------------------------------- 1 | // Package utils provides common sub commands and command flags. 2 | package utils 3 | 4 | import ( 5 | "os" 6 | "os/signal" 7 | "path/filepath" 8 | "sync" 9 | "syscall" 10 | "time" 11 | 12 | "github.com/anyswap/CrossChain-Router/v3/log" 13 | "github.com/anyswap/CrossChain-Router/v3/params" 14 | "github.com/urfave/cli/v2" 15 | ) 16 | 17 | var ( 18 | clientIdentifier string 19 | gitCommit string 20 | gitDate string 21 | ) 22 | 23 | // catch signal and cleanup related 24 | var ( 25 | CleanupChan = make(chan struct{}) 26 | TopWaitGroup = new(sync.WaitGroup) 27 | ) 28 | 29 | // NewApp creates an app with sane defaults. 30 | func NewApp(identifier, gitcommit, gitdate, usage string) *cli.App { 31 | notifySignals() 32 | clientIdentifier = identifier 33 | gitCommit = gitcommit 34 | gitDate = gitdate 35 | app := cli.NewApp() 36 | app.Name = filepath.Base(os.Args[0]) 37 | app.Version = params.VersionWithCommit(gitCommit, gitDate) 38 | app.Usage = usage 39 | return app 40 | } 41 | 42 | func notifySignals() { 43 | signal.Reset() // to cancal imported mod (eg. okex) to catch signal and call os.Exit 44 | signalChan := make(chan os.Signal, 1) 45 | signal.Notify(signalChan, 46 | os.Interrupt, 47 | syscall.SIGINT, 48 | syscall.SIGTERM, 49 | syscall.SIGQUIT, 50 | syscall.SIGHUP, 51 | ) 52 | go func() { 53 | sig := <-signalChan 54 | log.Info("receive signal", "signal", sig) 55 | log.Info("notify others to do clean up") 56 | close(CleanupChan) 57 | 58 | go func() { 59 | for i := 1; i <= 5; i++ { 60 | sig := <-signalChan 61 | log.Info("receive multiple (5) signals to exit", "signal", sig, "count", i) 62 | } 63 | os.Exit(1) 64 | }() 65 | 66 | <-time.After(5 * time.Second) 67 | os.Exit(1) 68 | }() 69 | } 70 | 71 | // IsCleanuping is cleanuping 72 | func IsCleanuping() bool { 73 | select { 74 | case <-CleanupChan: 75 | return true 76 | default: 77 | return false 78 | } 79 | } 80 | 81 | // WaitAndCleanup wait and cleanup 82 | func WaitAndCleanup(doCleanup func()) { 83 | <-CleanupChan 84 | doCleanup() 85 | } 86 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/crypto/hash_test.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/anyswap/CrossChain-Router/v3/tokens/ripple/rubblelabs/ripple/testing" 7 | . "gopkg.in/check.v1" 8 | ) 9 | 10 | func Test(t *testing.T) { TestingT(t) } 11 | 12 | type HashSuite struct{} 13 | 14 | var _ = Suite(&HashSuite{}) 15 | 16 | var testAccounts = map[string]struct { 17 | Account, Secret string 18 | }{ 19 | "alice": {"rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn", "alice"}, 20 | "bob": {"rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", "bob"}, 21 | "carol": {"rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW", "carol"}, 22 | "dan": {"rJ85Mok8YRNxSo7NnxKGrPuk29uAeZQqwZ", "dan"}, 23 | "bitstamp": {"r4jKmc2nQb5yEU6eycefiNKGHTU5NQJASx", "bitstamp"}, 24 | "mtgox": {"rGihwhaqU8g7ahwAvTq6iX5rvsfcbgZw6v", "mtgox"}, 25 | "amazon": {"rhheXqX7bDnXePJeMHhubDDvw2uUTtenPd", "amazon"}, 26 | "root": {"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "masterpassphrase"}, 27 | } 28 | 29 | var accountTests = TestSlice{ 30 | {accountCheck("0").Value().String(), Equals, "0", "Parse 0"}, 31 | {accountCheck("0").String(), Equals, ACCOUNT_ZERO, "Parse 0 export"}, 32 | {accountCheck("1").Value().String(), Equals, "1", "Parse 1"}, 33 | {accountCheck("1").String(), Equals, ACCOUNT_ONE, "Parse 1 export"}, 34 | {accountCheck(ACCOUNT_ZERO).String(), Equals, ACCOUNT_ZERO, "Parse rrrrrrrrrrrrrrrrrrrrrhoLvTp export"}, 35 | {accountCheck(ACCOUNT_ONE).String(), Equals, ACCOUNT_ONE, "Parse rrrrrrrrrrrrrrrrrrrrBZbvji export"}, 36 | {accountCheck(testAccounts["mtgox"].Account).String(), Equals, testAccounts["mtgox"].Account, "Parse mtgox export"}, 37 | {accountCheck(ACCOUNT_ZERO), Not(Equals), nil, "IsValid rrrrrrrrrrrrrrrrrrrrrhoLvTp"}, 38 | {ErrorCheck(NewRippleHash("rrrrrrrrrrrrrrrrrrrrrhoLvT")), ErrorMatches, "Bad Base58 checksum:.*", "IsValid rrrrrrrrrrrrrrrrrrrrrhoLvT"}, 39 | } 40 | 41 | func accountCheck(v interface{}) Hash { 42 | if a, err := NewRippleHash(v.(string)); err != nil { 43 | panic(err) 44 | } else { 45 | return a 46 | } 47 | } 48 | 49 | func (s *HashSuite) TestHashes(c *C) { 50 | accountTests.Test(c) 51 | } 52 | -------------------------------------------------------------------------------- /common/size.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The go-ethereum Authors 2 | // This file is part of the go-ethereum library. 3 | // 4 | // The go-ethereum library is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Lesser General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // The go-ethereum library is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with the go-ethereum library. If not, see . 16 | 17 | // Package common - common tools 18 | //nolint 19 | package common 20 | 21 | import ( 22 | "fmt" 23 | ) 24 | 25 | // StorageSize is a wrapper around a float value that supports user friendly 26 | // formatting. 27 | type StorageSize float64 28 | 29 | // String implements the stringer interface. 30 | func (s StorageSize) String() string { 31 | if s > 1099511627776 { 32 | return fmt.Sprintf("%.2f TiB", s/1099511627776) 33 | } else if s > 1073741824 { 34 | return fmt.Sprintf("%.2f GiB", s/1073741824) 35 | } else if s > 1048576 { 36 | return fmt.Sprintf("%.2f MiB", s/1048576) 37 | } else if s > 1024 { 38 | return fmt.Sprintf("%.2f KiB", s/1024) 39 | } else { 40 | return fmt.Sprintf("%.2f B", s) 41 | } 42 | } 43 | 44 | // TerminalString implements log.TerminalStringer, formatting a string for console 45 | // output during logging. 46 | func (s StorageSize) TerminalString() string { 47 | if s > 1099511627776 { 48 | return fmt.Sprintf("%.2fTiB", s/1099511627776) 49 | } else if s > 1073741824 { 50 | return fmt.Sprintf("%.2fGiB", s/1073741824) 51 | } else if s > 1048576 { 52 | return fmt.Sprintf("%.2fMiB", s/1048576) 53 | } else if s > 1024 { 54 | return fmt.Sprintf("%.2fKiB", s/1024) 55 | } else { 56 | return fmt.Sprintf("%.2fB", s) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tokens/stellar/address_test.go: -------------------------------------------------------------------------------- 1 | package stellar 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/common" 7 | ) 8 | 9 | func TestIsValidAddress(t *testing.T) { 10 | cases := []struct { 11 | Addr string 12 | Expected bool 13 | }{ 14 | {"GCHH22AXHDDXET47Q3YKSANZ74GAAWEIMECQ3ZNFVM3SJY2LGYYPFLUH", true}, 15 | {"gchh22axhddxet47q3yksanz74gaaweimecq3znfvm3sjy2lgyypfluh", false}, 16 | {"0xEDbe0d03d8022012a03d5535e8677681dbbd9bbd", false}, 17 | } 18 | b := NewCrossChainBridge("1000005786703") 19 | 20 | for _, c := range cases { 21 | t.Run(c.Addr, func(t *testing.T) { 22 | if ans := b.IsValidAddress(c.Addr); ans != c.Expected { 23 | t.Fatalf("%s expected %v, but %v got", c.Addr, c.Expected, ans) 24 | } 25 | }) 26 | } 27 | } 28 | 29 | func TestPublicKeyToAddress(t *testing.T) { 30 | cases := []struct { 31 | Pubkey string 32 | Expected string 33 | }{ 34 | {"be0d03d8022012a03d5535e8677681dbbd9bbd130a3593388a61454129f5c294", "GC7A2A6YAIQBFIB5KU26QZ3WQHN33G55CMFDLEZYRJQUKQJJ6XBJJPJJ"}, 35 | {"146f71db711bc259176f9bcba1756308d2a7af0f1c0b90deece65997a84c8f56", "GAKG64O3OEN4EWIXN6N4XILVMMENFJ5PB4OAXEG65TTFTF5IJSHVMBIC"}, 36 | } 37 | for _, c := range cases { 38 | t.Run(c.Pubkey, func(t *testing.T) { 39 | if ans, err := PublicKeyToAddress(common.Hex2Bytes(c.Pubkey)); err != nil || ans != c.Expected { 40 | t.Fatalf("%s expected %v, but %v got err:%v", c.Pubkey, c.Expected, ans, err) 41 | } 42 | }) 43 | } 44 | } 45 | 46 | func TestVerifyMPCPubKey(t *testing.T) { 47 | cases := []struct { 48 | Pubkey string 49 | Addr string 50 | }{ 51 | {"EDbe0d03d8022012a03d5535e8677681dbbd9bbd130a3593388a61454129f5c294", "GC7A2A6YAIQBFIB5KU26QZ3WQHN33G55CMFDLEZYRJQUKQJJ6XBJJPJJ"}, 52 | {"146f71db711bc259176f9bcba1756308d2a7af0f1c0b90deece65997a84c8f56", "GAKG64O3OEN4EWIXN6N4XILVMMENFJ5PB4OAXEG65TTFTF5IJSHVMBIC"}, 53 | } 54 | for _, c := range cases { 55 | t.Run(c.Pubkey, func(t *testing.T) { 56 | if ans := VerifyMPCPubKey(c.Addr, c.Pubkey); ans != nil { 57 | t.Fatalf("%s expected %v, but got err:%v", c.Pubkey, c.Addr, ans) 58 | } 59 | }) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tokens/base/reswapable.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/router" 7 | "github.com/anyswap/CrossChain-Router/v3/tokens" 8 | ) 9 | 10 | type ReSwapableBridgeBase struct { 11 | reswapMaxValue uint64 12 | txTimeout uint64 13 | } 14 | 15 | // NewNonceSetterBase new base nonce setter 16 | func NewReSwapableBridgeBase() *ReSwapableBridgeBase { 17 | return &ReSwapableBridgeBase{ 18 | reswapMaxValue: uint64(0), 19 | txTimeout: uint64(60 * 10), 20 | } 21 | } 22 | 23 | func (b *ReSwapableBridgeBase) SetReswapMaxValueRate(rate uint64) { 24 | b.reswapMaxValue = rate 25 | } 26 | 27 | func (b *ReSwapableBridgeBase) SetTimeoutConfig(txTimeout uint64) { 28 | b.txTimeout = txTimeout 29 | } 30 | 31 | func (b *ReSwapableBridgeBase) GetTimeoutConfig() uint64 { 32 | return b.txTimeout 33 | } 34 | 35 | func (b *ReSwapableBridgeBase) SetTxTimeout(args *tokens.BuildTxArgs, txTimeout *uint64) { 36 | if args.ERC20SwapInfo == nil { 37 | return 38 | } 39 | if args.Extra.TTL != nil { 40 | return 41 | } 42 | if b.reswapMaxValue == 0 { 43 | return 44 | } 45 | swapInfo := args.ERC20SwapInfo 46 | tokenID := swapInfo.TokenID 47 | // if params.IsInBigValueWhitelist(tokenID, args.From) || 48 | // params.IsInBigValueWhitelist(tokenID, args.To) { 49 | // args.Extra.TTL = txTimeout 50 | // return 51 | // } 52 | bridge := router.GetBridgeByChainID(args.FromChainID.String()) 53 | if bridge == nil { 54 | return 55 | } 56 | tokenCfg := bridge.GetTokenConfig(swapInfo.Token) 57 | if tokenCfg == nil { 58 | return 59 | } 60 | fromDecimals := tokenCfg.Decimals 61 | bigValueThreshold := tokens.GetBigValueThreshold(tokenID, args.FromChainID.String(), args.ToChainID.String(), fromDecimals) 62 | bigValueThreshold.Mul(bigValueThreshold, new(big.Int).SetUint64(b.reswapMaxValue)) 63 | bigValueThreshold.Div(bigValueThreshold, big.NewInt(1000)) 64 | if args.SwapValue.Cmp(bigValueThreshold) <= 0 { 65 | args.Extra.TTL = txTimeout 66 | } 67 | } 68 | 69 | func (b *ReSwapableBridgeBase) IsTxTimeout(txValue, currentValue *uint64) bool { 70 | return txValue != nil && *txValue > 0 && *currentValue > *txValue 71 | } 72 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/crypto/signature.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "crypto/ed25519" 5 | "fmt" 6 | 7 | "github.com/btcsuite/btcd/btcec" 8 | ) 9 | 10 | func Sign(privateKey, hash, msg []byte) ([]byte, error) { 11 | switch len(privateKey) { 12 | case ed25519.PrivateKeySize: 13 | return signEd25519(privateKey, msg) 14 | case btcec.PrivKeyBytesLen: 15 | return signECDSA(privateKey, hash) 16 | default: 17 | return nil, fmt.Errorf("Unknown private key format") 18 | } 19 | } 20 | 21 | func Verify(publicKey, hash, msg, signature []byte) (bool, error) { 22 | switch publicKey[0] { 23 | case 0xED: 24 | return verifyEd25519(publicKey, signature, msg) 25 | case 0x02, 0x03, 0x04: 26 | return verifyECDSA(publicKey, signature, hash) 27 | default: 28 | return false, fmt.Errorf("Unknown public key format") 29 | } 30 | } 31 | 32 | func signEd25519(privateKey, msg []byte) ([]byte, error) { 33 | return ed25519.Sign(privateKey, msg)[:], nil 34 | } 35 | 36 | func verifyEd25519(pubKey, signature, msg []byte) (bool, error) { 37 | switch { 38 | case len(pubKey) != ed25519.PublicKeySize+1: 39 | return false, fmt.Errorf("Wrong public key length: %d", len(pubKey)) 40 | case pubKey[0] != 0xED: 41 | return false, fmt.Errorf("Wrong public format:") 42 | case len(signature) != ed25519.SignatureSize: 43 | return false, fmt.Errorf("Wrong Signature length: %d", len(signature)) 44 | default: 45 | return ed25519.Verify(pubKey[1:], msg, signature), nil 46 | } 47 | } 48 | 49 | // Returns DER encoded signature from input hash 50 | func signECDSA(privateKey, hash []byte) ([]byte, error) { 51 | priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), privateKey) 52 | sig, err := priv.Sign(hash) 53 | if err != nil { 54 | return nil, err 55 | } 56 | return sig.Serialize(), nil 57 | } 58 | 59 | // Verifies a hash using DER encoded signature 60 | func verifyECDSA(pubKey, signature, hash []byte) (bool, error) { 61 | sig, err := btcec.ParseDERSignature(signature, btcec.S256()) 62 | if err != nil { 63 | return false, err 64 | } 65 | pk, err := btcec.ParsePubKey(pubKey, btcec.S256()) 66 | if err != nil { 67 | return false, nil 68 | } 69 | return sig.Verify(hash, pk), nil 70 | } 71 | -------------------------------------------------------------------------------- /tokens/cosmos/README.md: -------------------------------------------------------------------------------- 1 | # Cosmos ecosystem 2 | 3 | This document use cosmos-hub as an example. 4 | 5 | ## cosmosHub 6 | 7 | ```text 8 | 1) chainId 9 | mainnet: 1293698254146 10 | testnet: 1293698254147 11 | 12 | 2) apiUrl 13 | mainnet: https://cosmos-mainnet-rpc.allthatnode.com:1317 14 | testnet: https://cosmos-testnet-rpc.allthatnode.com:1317 15 | 16 | 3) explorer: 17 | https://atomscan.com/ 18 | 19 | 4) faucet: 20 | https://www.allthatnode.com/faucet/cosmos.dsrv 21 | ``` 22 | 23 | ## tools 24 | 25 | ```text 26 | 1) getChainId 27 | go run ./tokens/cosmos/tools/getStubChainID/main.go -n COSMOSHUB -p testnet 28 | 29 | testnet: 1293698254147 30 | 31 | 2) publicKeyToAddress 32 | go run ./tokens/cosmos/tools/publicKeyToAddress/main.go -p 0x0468438a94627b0de2b6a7c9af99136ef7e607f7944b749c3534bb27a89e742d583b1c8b3aecfae45dea2ac58730aa6ba654c73c435d44755e5cd1500c8f4d036b -prefix cosmos 33 | 34 | addr: cosmos10yyn2er9k5cs9qn55l7t23yxxk7egecpw9lw90 35 | ``` 36 | 37 | ## config setting 38 | 39 | ```text 40 | 1) chainConfig 41 | 42 | routerContract: mpc address 43 | extra: format is `prefix:Denom` 44 | 45 | for example, 46 | 47 | # cosmosHub 48 | cosmos:uatom 49 | 50 | # sei 51 | sei:usei 52 | 53 | # coreum 54 | devcore:ducore 55 | 56 | # osmosis 57 | osmo:uosmo 58 | 59 | 2) tokenConfig 60 | 61 | for meta coin, 62 | 63 | tokenAddress: usei 64 | decimals: 6 65 | 66 | for other tokens, 67 | 68 | tokenAddress: factory/{creator}/{subdenom} 69 | decimals: 6 70 | 71 | 72 | 3) example 73 | 74 | https://rinkeby.etherscan.io/address/0x4342F2b5224a43541BE7C8F39B92D7fEaA74d038 75 | ``` 76 | 77 | ## router mechanism 78 | 79 | 1. Swapout from cosmos to other chain 80 | 81 | user send asset to `mpc` address with memo of the following format 82 | 83 | ```text 84 | bindAddress:toChainID 85 | ``` 86 | 87 | to specify route asset to which address (`bindAddress`) 88 | and to which destination blockchain (`toChainID`) 89 | 90 | 2. Swapin from other chain to cosmos 91 | 92 | ```solidity 93 | function anySwapOut(address token, string memory to, uint amount, uint toChainID) 94 | ``` 95 | 96 | `to` is the receiver address on cosmos. 97 | -------------------------------------------------------------------------------- /tokens/solana/tools/common.go: -------------------------------------------------------------------------------- 1 | package solanatools 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/anyswap/CrossChain-Router/v3/common" 8 | "github.com/anyswap/CrossChain-Router/v3/mpc" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/solana" 10 | "github.com/anyswap/CrossChain-Router/v3/tokens/solana/types" 11 | ) 12 | 13 | type Signer struct { 14 | PublicKey string 15 | PrivateKey string 16 | } 17 | 18 | func SignAndSend(mpcConfig *mpc.Config, bridge *solana.Bridge, signers []*Signer, tx *types.Transaction) string { 19 | signerKeys := tx.Message.SignerKeys() 20 | if len(signerKeys) != len(signers) { 21 | log.Fatal("wrong number of signer keys") 22 | } 23 | 24 | var err error 25 | var calctxHash string 26 | 27 | msgContent, err := tx.Message.Serialize() 28 | if err != nil { 29 | log.Fatal("unable to encode message for signing", err) 30 | } 31 | 32 | for i := 0; i < len(signers); i++ { 33 | var signer = signers[i] 34 | if signer.PrivateKey != "" { 35 | signAccount, _ := types.AccountFromPrivateKeyBase58(signer.PrivateKey) 36 | signature, _ := signAccount.PrivateKey.Sign(msgContent) 37 | tx.Signatures = append(tx.Signatures, signature) 38 | if i == 0 { 39 | calctxHash = signature.String() 40 | } 41 | } else { 42 | var keyID string 43 | var rsvs []string 44 | 45 | keyID, rsvs, err = mpcConfig.DoSignOneED(common.ToHex(types.MustPublicKeyFromBase58(signer.PublicKey).ToSlice())[2:], common.ToHex(msgContent[:]), "solanaChangeMPC") 46 | if len(rsvs) != 1 { 47 | log.Fatal("get sign status require one rsv but return many", err) 48 | } 49 | rsv := rsvs[0] 50 | sig, err := types.NewSignatureFromString(rsv) 51 | if err != nil { 52 | log.Fatal("get signature from rsv failed", "keyID", keyID, "txid", err) 53 | } 54 | tx.Signatures = append(tx.Signatures, sig) 55 | if i == 0 { 56 | calctxHash = sig.String() 57 | } 58 | } 59 | } 60 | fmt.Println("txhash", calctxHash) 61 | 62 | sendTxHash, err := bridge.SendTransaction(tx) 63 | if err != nil { 64 | log.Fatal("SendTransaction err", err) 65 | } 66 | if sendTxHash != calctxHash { 67 | log.Fatal("SendTransaction sendTxHash not same") 68 | } 69 | return sendTxHash 70 | } 71 | -------------------------------------------------------------------------------- /router/bridge/new.go: -------------------------------------------------------------------------------- 1 | package bridge 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/anyswap/CrossChain-Router/v3/log" 7 | "github.com/anyswap/CrossChain-Router/v3/tokens" 8 | "github.com/anyswap/CrossChain-Router/v3/tokens/aptos" 9 | "github.com/anyswap/CrossChain-Router/v3/tokens/btc" 10 | "github.com/anyswap/CrossChain-Router/v3/tokens/cardano" 11 | "github.com/anyswap/CrossChain-Router/v3/tokens/cosmos" 12 | "github.com/anyswap/CrossChain-Router/v3/tokens/eth" 13 | "github.com/anyswap/CrossChain-Router/v3/tokens/flow" 14 | "github.com/anyswap/CrossChain-Router/v3/tokens/iota" 15 | "github.com/anyswap/CrossChain-Router/v3/tokens/near" 16 | "github.com/anyswap/CrossChain-Router/v3/tokens/reef" 17 | "github.com/anyswap/CrossChain-Router/v3/tokens/ripple" 18 | "github.com/anyswap/CrossChain-Router/v3/tokens/solana" 19 | "github.com/anyswap/CrossChain-Router/v3/tokens/stellar" 20 | "github.com/anyswap/CrossChain-Router/v3/tokens/tron" 21 | ) 22 | 23 | // NewCrossChainBridge new bridge 24 | func NewCrossChainBridge(chainID *big.Int) tokens.IBridge { 25 | switch { 26 | case reef.SupportsChainID(chainID): 27 | return reef.NewCrossChainBridge() 28 | case solana.SupportChainID(chainID): 29 | return solana.NewCrossChainBridge() 30 | case cosmos.SupportsChainID(chainID): 31 | return cosmos.NewCrossChainBridge() 32 | case btc.SupportsChainID(chainID): 33 | return btc.NewCrossChainBridge() 34 | case cardano.SupportsChainID(chainID): 35 | return cardano.NewCrossChainBridge() 36 | case aptos.SupportsChainID(chainID): 37 | return aptos.NewCrossChainBridge() 38 | case tron.SupportsChainID(chainID): 39 | return tron.NewCrossChainBridge() 40 | case near.SupportsChainID(chainID): 41 | return near.NewCrossChainBridge() 42 | case iota.SupportsChainID(chainID): 43 | return iota.NewCrossChainBridge() 44 | case ripple.SupportsChainID(chainID): 45 | return ripple.NewCrossChainBridge() 46 | case stellar.SupportsChainID(chainID): 47 | return stellar.NewCrossChainBridge(chainID.String()) 48 | case flow.SupportsChainID(chainID): 49 | return flow.NewCrossChainBridge() 50 | case chainID.Sign() <= 0: 51 | log.Fatal("wrong chainID", "chainID", chainID) 52 | default: 53 | return eth.NewCrossChainBridge() 54 | } 55 | return nil 56 | } 57 | -------------------------------------------------------------------------------- /tokens/ripple/rubblelabs/ripple/crypto/base58.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "math/big" 7 | "strings" 8 | ) 9 | 10 | // Purloined from https://github.com/conformal/btcutil/ 11 | 12 | var bigRadix = big.NewInt(58) 13 | var bigZero = big.NewInt(0) 14 | 15 | // Base58Decode decodes a modified base58 string to a byte slice and checks checksum. 16 | func Base58Decode(b, alphabet string) ([]byte, error) { 17 | if len(b) < 5 { 18 | return nil, fmt.Errorf("Base58 string too short: %s", b) 19 | } 20 | answer := big.NewInt(0) 21 | j := big.NewInt(1) 22 | 23 | for i := len(b) - 1; i >= 0; i-- { 24 | tmp := strings.IndexAny(alphabet, string(b[i])) 25 | if tmp == -1 { 26 | return nil, fmt.Errorf("Bad Base58 string: %s", b) 27 | } 28 | idx := big.NewInt(int64(tmp)) 29 | tmp1 := big.NewInt(0) 30 | tmp1.Mul(j, idx) 31 | 32 | answer.Add(answer, tmp1) 33 | j.Mul(j, bigRadix) 34 | } 35 | 36 | tmpval := answer.Bytes() 37 | 38 | var numZeros int 39 | for numZeros = 0; numZeros < len(b); numZeros++ { 40 | if b[numZeros] != alphabet[0] { 41 | break 42 | } 43 | } 44 | flen := numZeros + len(tmpval) 45 | val := make([]byte, flen, flen) 46 | copy(val[numZeros:], tmpval) 47 | 48 | // Check checksum 49 | checksum := DoubleSha256(val[0 : len(val)-4]) 50 | expected := val[len(val)-4:] 51 | if !bytes.Equal(checksum[0:4], expected) { 52 | return nil, fmt.Errorf("Bad Base58 checksum: %v expected %v", checksum, expected) 53 | } 54 | return val, nil 55 | } 56 | 57 | // Base58Encode encodes a byte slice to a modified base58 string. 58 | func Base58Encode(b []byte, alphabet string) string { 59 | checksum := DoubleSha256(b) 60 | b = append(b, checksum[0:4]...) 61 | x := new(big.Int) 62 | x.SetBytes(b) 63 | 64 | answer := make([]byte, 0) 65 | for x.Cmp(bigZero) > 0 { 66 | mod := new(big.Int) 67 | x.DivMod(x, bigRadix, mod) 68 | answer = append(answer, alphabet[mod.Int64()]) 69 | } 70 | 71 | // leading zero bytes 72 | for _, i := range b { 73 | if i != 0 { 74 | break 75 | } 76 | answer = append(answer, alphabet[0]) 77 | } 78 | 79 | // reverse 80 | alen := len(answer) 81 | for i := 0; i < alen/2; i++ { 82 | answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i] 83 | } 84 | 85 | return string(answer) 86 | } 87 | -------------------------------------------------------------------------------- /tokens/cardano/README_deployment.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | ### 1. chainId 4 | mainnet: 1645027868239 5 | testnet(preprod): 1645027868240 6 | 7 | ### 2. url 8 | mainnet: https://graphql-api.mainnet.dandelion.link/ 9 | testnet: https://graphql-api.testnet.dandelion.link/ 10 | 11 | ### 3. register blockfrost 12 | https://blockfrost.io/ to get api key 13 | 14 | ### 4. route config key points 15 | ``` 16 | [Extra.Customs.1645027868240] 17 | APIKey = "api key" # blockfrost APIKEY 18 | AssetPolicyKey = "policy seed" # Policykey seed 19 | AppendName = "true" #config whether the policy is the same for all asset, policy is same if set `false` 20 | UseAPI = "false" #config whether use the blockfrost api to query tx or tip .etc 21 | TxTimeout = "600" #config how many block solt passed when tx timeout, default is 600 22 | ReswapMaxAmountRate = "1" #config What thousandths of BigAmount will not auto reswap when swap amount above, `1` means 1‰ 23 | ``` 24 | 25 | ### 5. genMpcAddr 26 | go run tokens/cardano/tools/pubKeyToAddr/main.go -h 27 | 28 | ### 6. get some ADA 29 | Testnet: https://docs.cardano.org/cardano-testnet/tools/faucet 30 | 31 | ### 7. mint token 32 | go run tokens/cardano/tools/mintToken/main.go -h 33 | 34 | ### 8. set config contract 35 | 7.1 routerAddress is mpc address 36 | 7.2 tokenAddress is policyId.assetName if token not ADA 37 | tokenAddress is lovelace if token is ADA 38 | 39 | ### 9. send swapout tx 40 | go run tokens/cardano/tools/sendTransaction/main.go -h 41 | 42 | ### 10.tools 43 | 44 | - go run tokens/cardano/tools/mintToken/main.go -h 45 | - go run tokens/cardano/tools/pubKeyToAddr/main.go -h 46 | - go run tokens/cardano/tools/newWallet/main.go -h 47 | - go run tokens/cardano/tools/newToken/main.go -h 48 | - go run tokens/cardano/tools/queryUtxos/main.go -h 49 | - go run tokens/cardano/tools/sendTransaction/main.go -h 50 | 51 | # DevOps 52 | #### run cardano node 53 | 54 | ```text 55 | https://developers.cardano.org/docs/get-started/installing-cardano-node/#overview 56 | ``` 57 | 58 | #### Graphql 59 | 60 | ```text 61 | https://github.com/input-output-hk/cardano-graphql 62 | ``` 63 | 64 | #### minting native tokenclear 65 | 66 | ```text 67 | https://docs.cardano.org/native-tokens/getting-started 68 | ``` 69 | 70 | #### scaner 71 | tokens/cardano/tools/scan/main.go -------------------------------------------------------------------------------- /mongodb/dbinit.go: -------------------------------------------------------------------------------- 1 | // Package mongodb is a wrapper of mongo-go-driver that 2 | // defines the collections and CRUD apis on them. 3 | package mongodb 4 | 5 | import ( 6 | "context" 7 | "sync" 8 | "time" 9 | 10 | "github.com/anyswap/CrossChain-Router/v3/cmd/utils" 11 | "github.com/anyswap/CrossChain-Router/v3/log" 12 | 13 | "go.mongodb.org/mongo-driver/mongo" 14 | "go.mongodb.org/mongo-driver/mongo/options" 15 | ) 16 | 17 | var ( 18 | client *mongo.Client 19 | clientCtx = context.Background() 20 | 21 | appIdentifier string 22 | databaseName string 23 | 24 | // MgoWaitGroup wait all mongodb related task done 25 | MgoWaitGroup = new(sync.WaitGroup) 26 | ) 27 | 28 | // HasClient has client 29 | func HasClient() bool { 30 | return client != nil 31 | } 32 | 33 | // MongoServerInit int mongodb server session 34 | func MongoServerInit(appName string, hosts []string, dbName, user, pass string) { 35 | appIdentifier = appName 36 | databaseName = dbName 37 | 38 | clientOpts := &options.ClientOptions{ 39 | AppName: &appName, 40 | Hosts: hosts, 41 | Auth: &options.Credential{ 42 | AuthSource: dbName, 43 | Username: user, 44 | Password: pass, 45 | }, 46 | } 47 | 48 | if err := connect(clientOpts); err != nil { 49 | log.Fatal("[mongodb] connect database failed", "hosts", hosts, "dbName", dbName, "appName", appName, "err", err) 50 | } 51 | 52 | log.Info("[mongodb] connect database success", "hosts", hosts, "dbName", dbName, "appName", appName) 53 | 54 | utils.TopWaitGroup.Add(1) 55 | go utils.WaitAndCleanup(doCleanup) 56 | } 57 | 58 | func doCleanup() { 59 | defer utils.TopWaitGroup.Done() 60 | MgoWaitGroup.Wait() 61 | 62 | err := client.Disconnect(clientCtx) 63 | if err != nil { 64 | log.Error("[mongodb] close connection failed", "appName", appIdentifier, "err", err) 65 | } else { 66 | log.Info("[mongodb] close connection success", "appName", appIdentifier) 67 | } 68 | } 69 | 70 | func connect(opts *options.ClientOptions) (err error) { 71 | ctx, cancel := context.WithTimeout(clientCtx, 10*time.Second) 72 | defer cancel() 73 | 74 | client, err = mongo.Connect(ctx, opts) 75 | if err != nil { 76 | return err 77 | } 78 | 79 | err = client.Ping(clientCtx, nil) 80 | if err != nil { 81 | return err 82 | } 83 | 84 | initCollections() 85 | return nil 86 | } 87 | -------------------------------------------------------------------------------- /tokens/eth/callapi/kusama.go: -------------------------------------------------------------------------------- 1 | package callapi 2 | 3 | import ( 4 | "github.com/anyswap/CrossChain-Router/v3/common" 5 | "github.com/anyswap/CrossChain-Router/v3/common/hexutil" 6 | "github.com/anyswap/CrossChain-Router/v3/rpc/client" 7 | "github.com/anyswap/CrossChain-Router/v3/types" 8 | ) 9 | 10 | // ------------------------ kusama override apis ----------------------------- 11 | 12 | // KsmHeader struct 13 | type KsmHeader struct { 14 | ParentHash *common.Hash `json:"parentHash"` 15 | Number *hexutil.Big `json:"number"` 16 | } 17 | 18 | // KsmGetBlockConfirmations get block confirmations 19 | func KsmGetBlockConfirmations(b EvmBridge, receipt *types.RPCTxReceipt) (uint64, error) { 20 | latest, err := KsmGetFinalizedBlockNumber(b) 21 | if err != nil { 22 | return 0, err 23 | } 24 | blockNumber := receipt.BlockNumber.ToInt().Uint64() 25 | if latest > blockNumber { 26 | return latest - blockNumber, nil 27 | } 28 | return 0, nil 29 | } 30 | 31 | // KsmGetFinalizedBlockNumber call chain_getFinalizedHead and chain_getHeader 32 | func KsmGetFinalizedBlockNumber(b EvmBridge) (latest uint64, err error) { 33 | gateway := b.GetGatewayConfig() 34 | urls := gateway.AllGatewayURLs 35 | blockHash, err := KsmGetFinalizedHead(urls) 36 | if err != nil { 37 | return 0, err 38 | } 39 | header, err := KsmGetHeader(urls, blockHash.String()) 40 | if err != nil { 41 | return 0, err 42 | } 43 | return header.Number.ToInt().Uint64(), nil 44 | } 45 | 46 | // ------------------------ kusama specific apis ----------------------------- 47 | 48 | // KsmGetFinalizedHead call chain_getFinalizedHead 49 | func KsmGetFinalizedHead(urls []string) (result *common.Hash, err error) { 50 | for _, url := range urls { 51 | err = client.RPCPost(&result, url, "chain_getFinalizedHead") 52 | if err == nil && result != nil { 53 | return result, nil 54 | } 55 | } 56 | return nil, wrapRPCQueryError(err, "chain_getFinalizedHead") 57 | } 58 | 59 | // KsmGetHeader call chain_getHeader 60 | func KsmGetHeader(urls []string, blockHash string) (result *KsmHeader, err error) { 61 | for _, url := range urls { 62 | err = client.RPCPost(&result, url, "chain_getHeader", blockHash) 63 | if err == nil && result != nil { 64 | return result, nil 65 | } 66 | } 67 | return nil, wrapRPCQueryError(err, "chain_getHeader", blockHash) 68 | } 69 | -------------------------------------------------------------------------------- /common/big.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The go-ethereum Authors 2 | // This file is part of the go-ethereum library. 3 | // 4 | // The go-ethereum library is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU Lesser General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // The go-ethereum library is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with the go-ethereum library. If not, see . 16 | 17 | package common 18 | 19 | import ( 20 | "math" 21 | "math/big" 22 | ) 23 | 24 | // Common big integers often used 25 | var ( 26 | Big1 = big.NewInt(1) 27 | Big2 = big.NewInt(2) 28 | Big3 = big.NewInt(3) 29 | Big0 = big.NewInt(0) 30 | Big32 = big.NewInt(32) 31 | Big256 = big.NewInt(256) 32 | Big257 = big.NewInt(257) 33 | 34 | BigMaxUint64 = new(big.Int).SetUint64(math.MaxUint64) 35 | ) 36 | 37 | // MarshalBigInt marshalls big int into text string for consistent encoding 38 | func MarshalBigInt(i *big.Int) (string, error) { 39 | bz, err := i.MarshalText() 40 | if err != nil { 41 | return "", err 42 | } 43 | return string(bz), nil 44 | } 45 | 46 | // MustMarshalBigInt marshalls big int into text string for consistent encoding. 47 | // It panics if an error is encountered. 48 | func MustMarshalBigInt(i *big.Int) string { 49 | str, err := MarshalBigInt(i) 50 | if err != nil { 51 | panic(err) 52 | } 53 | return str 54 | } 55 | 56 | // UnmarshalBigInt unmarshalls string from *big.Int 57 | func UnmarshalBigInt(s string) (*big.Int, error) { 58 | ret := new(big.Int) 59 | err := ret.UnmarshalText([]byte(s)) 60 | if err != nil { 61 | return nil, err 62 | } 63 | return ret, nil 64 | } 65 | 66 | // MustUnmarshalBigInt unmarshalls string from *big.Int. 67 | // It panics if an error is encountered. 68 | func MustUnmarshalBigInt(s string) *big.Int { 69 | ret, err := UnmarshalBigInt(s) 70 | if err != nil { 71 | panic(err) 72 | } 73 | return ret 74 | } 75 | -------------------------------------------------------------------------------- /log/logger_test.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | var ( 12 | now = time.Now().Unix() 13 | err = fmt.Errorf("error message") 14 | ) 15 | 16 | // Fatal Fatalf Fatalln is not test 17 | func TestLogger(t *testing.T) { 18 | SetLogger(6, false, true) 19 | 20 | WithFields("timestamp", now, "err", err).Tracef("test WithFields Tracef at %v", now) 21 | WithFields("timestamp", now, "err", err).Debugf("test WithFields Debugf at %v", now) 22 | WithFields("timestamp", now, "err", err).Infof("test WithFields Infof at %v", now) 23 | WithFields("timestamp", now, "err", err).Printf("test WithFields Printf at %v", now) 24 | WithFields("timestamp", now, "err", err).Warnf("test WithFields Warnf at %v", now) 25 | WithFields("timestamp", now, "err", err).Errorf("test WithFields Errorf at %v", now) 26 | assert.Panics(t, func() { WithFields("timestamp", now, "err", err).Panicf("test WithFields Panicf at %v", now) }, "not panic") 27 | 28 | Trace("test Trace", "timestamp", now, "err", err) 29 | Tracef("test Tracef, timestamp=%v err=%v", now, err) 30 | Traceln("test Traceln", "timestamp", now, "err", err) 31 | 32 | Debug("test Debug", "timestamp", now, "err", err) 33 | Debugf("test Debugf, timestamp=%v err=%v", now, err) 34 | Debugln("test Debugln", "timestamp", now, "err", err) 35 | 36 | Info("test Info", "timestamp", now, "err", err) 37 | Infof("test Infof, timestamp=%v err=%v", now, err) 38 | Infoln("test Infoln", "timestamp", now, "err", err) 39 | 40 | Print("test Print ", "timestamp", now, " err ", err) 41 | Printf("test Printf, timestamp=%v err=%v", now, err) 42 | Println("test Println", "timestamp", now, "err", err) 43 | 44 | Warn("test Warn", "timestamp", now, "err", err) 45 | Warnf("test Warnf, timestamp=%v err=%v", now, err) 46 | Warnln("test Warnln", "timestamp", now, "err", err) 47 | 48 | Error("test Error", "timestamp", now, "err", err) 49 | Errorf("test Errorf, timestamp=%v err=%v", now, err) 50 | Errorln("test Errorln", "timestamp", now, "err", err) 51 | 52 | assert.Panics(t, func() { Panic("test Panic", "timestamp", now, "err", err) }, "not panic") 53 | assert.Panics(t, func() { Panicf("test Panicf, timestamp=%v err=%v", now, err) }, "not panic") 54 | assert.Panics(t, func() { Panicln("test Panicln", "timestamp", now, "err", err) }, "not panic") 55 | } 56 | --------------------------------------------------------------------------------