ci: switch from ganache to anvil
This commit is contained in:
parent
fcabf0c99e
commit
77b4ddc812
|
@ -34,8 +34,7 @@ jobs:
|
||||||
kubectl config set-context ci --namespace=$DEPLOY_NS
|
kubectl config set-context ci --namespace=$DEPLOY_NS
|
||||||
kubectl config use-context ci
|
kubectl config use-context ci
|
||||||
|
|
||||||
# temporarily set --guardiand_loglevel=info to debug https://github.com/wormhole-foundation/wormhole/issues/3052
|
- run: tilt ci --timeout 45m0s -- --ci --namespace=$DEPLOY_NS --num=2
|
||||||
- run: tilt ci --timeout 45m0s -- --ci --namespace=$DEPLOY_NS --num=2 --guardiand_loglevel=info
|
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|
||||||
# Clean up k8s resources
|
# Clean up k8s resources
|
||||||
|
|
22
DEVELOP.md
22
DEVELOP.md
|
@ -37,7 +37,7 @@ Launch the devnet:
|
||||||
|
|
||||||
tilt up
|
tilt up
|
||||||
|
|
||||||
By default this runs a network consisting of one guardian, two ganache (Eth) chains, a Solana test validator, an Algorand sandbox, and LocalTerra for both Terra Classic and Terra 2. If you want to work on non-consensus parts of the code, running with a single guardian is easiest since you won't have to wait for k8s to restart all pods. See the usage guide below for arguments to customize the tilt network.
|
By default this runs a network consisting of one guardian, two anvil (Eth) chains, a Solana test validator, an Algorand sandbox, and LocalTerra for both Terra Classic and Terra 2. If you want to work on non-consensus parts of the code, running with a single guardian is easiest since you won't have to wait for k8s to restart all pods. See the usage guide below for arguments to customize the tilt network.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -140,28 +140,40 @@ To re-generate these files run `rm -rf node/pkg/proto && docker build --target g
|
||||||
|
|
||||||
### Call gRPC services
|
### Call gRPC services
|
||||||
|
|
||||||
<!-- cspell:disable-next-line -->
|
<!-- cspell:disable -->
|
||||||
|
|
||||||
tools/bin/grpcurl -protoset <(tools/bin/buf build -o -) -plaintext localhost:7072 spy.v1.SpyRPCService/SubscribeSignedVAA
|
tools/bin/grpcurl -protoset <(tools/bin/buf build -o -) -plaintext localhost:7072 spy.v1.SpyRPCService/SubscribeSignedVAA
|
||||||
|
|
||||||
|
<!-- cspell:enable -->
|
||||||
|
|
||||||
With parameters (using proto json encoding):
|
With parameters (using proto json encoding):
|
||||||
|
|
||||||
<!-- cspell:disable-next-line -->
|
<!-- cspell:disable -->
|
||||||
|
|
||||||
tools/bin/grpcurl -protoset <(tools/bin/buf build -o -) \
|
tools/bin/grpcurl -protoset <(tools/bin/buf build -o -) \
|
||||||
-d '{"filters": [{"emitter_filter": {"emitter_address": "574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d", "chain_id": "CHAIN_ID_SOLANA"}}]}' \
|
-d '{"filters": [{"emitter_filter": {"emitter_address": "574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d", "chain_id": "CHAIN_ID_SOLANA"}}]}' \
|
||||||
-plaintext localhost:7072 spy.v1.SpyRPCService/SubscribeSignedVAA
|
-plaintext localhost:7072 spy.v1.SpyRPCService/SubscribeSignedVAA
|
||||||
|
|
||||||
|
<!-- cspell:enable -->
|
||||||
|
|
||||||
### Post messages
|
### Post messages
|
||||||
|
|
||||||
To Solana:
|
To Solana:
|
||||||
|
|
||||||
<!-- cspell:disable-next-line -->
|
<!-- cspell:disable -->
|
||||||
|
|
||||||
kubectl exec solana-devnet-0 -c setup -- client post-message Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o 1 confirmed ffff
|
kubectl exec solana-devnet-0 -c setup -- client post-message Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o 1 confirmed ffff
|
||||||
|
|
||||||
|
<!-- cspell:enable -->
|
||||||
|
|
||||||
To Solana as CPI instruction:
|
To Solana as CPI instruction:
|
||||||
|
|
||||||
<!-- cspell:disable-next-line -->
|
<!-- cspell:disable -->
|
||||||
|
|
||||||
kubectl exec solana-devnet-0 -c setup -- client post-message --proxy CP1co2QMMoDPbsmV7PGcUTLFwyhgCgTXt25gLQ5LewE1 Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o 1 confirmed ffff
|
kubectl exec solana-devnet-0 -c setup -- client post-message --proxy CP1co2QMMoDPbsmV7PGcUTLFwyhgCgTXt25gLQ5LewE1 Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o 1 confirmed ffff
|
||||||
|
|
||||||
|
<!-- cspell:enable -->
|
||||||
|
|
||||||
### Observation Requests
|
### Observation Requests
|
||||||
|
|
||||||
kubectl exec -it guardian-0 -- /guardiand admin send-observation-request --socket /tmp/admin.sock 1 4636d8f7593c78a5092bed13dec765cc705752653db5eb1498168c92345cd389
|
kubectl exec -it guardian-0 -- /guardiand admin send-observation-request --socket /tmp/admin.sock 1 4636d8f7593c78a5092bed13dec765cc705752653db5eb1498168c92345cd389
|
||||||
|
|
4
Tiltfile
4
Tiltfile
|
@ -534,7 +534,7 @@ k8s_yaml_with_ns("devnet/eth-devnet.yaml")
|
||||||
k8s_resource(
|
k8s_resource(
|
||||||
"eth-devnet",
|
"eth-devnet",
|
||||||
port_forwards = [
|
port_forwards = [
|
||||||
port_forward(8545, name = "Ganache RPC [:8545]", host = webHost),
|
port_forward(8545, name = "Anvil RPC [:8545]", host = webHost),
|
||||||
],
|
],
|
||||||
labels = ["evm"],
|
labels = ["evm"],
|
||||||
trigger_mode = trigger_mode,
|
trigger_mode = trigger_mode,
|
||||||
|
@ -546,7 +546,7 @@ if evm2:
|
||||||
k8s_resource(
|
k8s_resource(
|
||||||
"eth-devnet2",
|
"eth-devnet2",
|
||||||
port_forwards = [
|
port_forwards = [
|
||||||
port_forward(8546, name = "Ganache RPC [:8546]", host = webHost),
|
port_forward(8546, 8545, name = "Anvil RPC [:8546]", host = webHost),
|
||||||
],
|
],
|
||||||
labels = ["evm"],
|
labels = ["evm"],
|
||||||
trigger_mode = trigger_mode,
|
trigger_mode = trigger_mode,
|
||||||
|
|
|
@ -31,19 +31,16 @@ spec:
|
||||||
spec:
|
spec:
|
||||||
terminationGracePeriodSeconds: 1
|
terminationGracePeriodSeconds: 1
|
||||||
containers:
|
containers:
|
||||||
- name: ganache
|
- name: anvil
|
||||||
image: eth-node
|
image: eth-node
|
||||||
command:
|
command:
|
||||||
- npx
|
- anvil
|
||||||
- ganache-cli
|
- --silent
|
||||||
- --logging.quiet
|
- --mnemonic=myth like bonus scare over problem client lizard pioneer submit female collect
|
||||||
- --wallet.defaultBalance=10000
|
- --block-time=1
|
||||||
- --wallet.deterministic
|
|
||||||
- --chain.time="1970-01-01T00:00:00+00:00"
|
|
||||||
- --host=0.0.0.0
|
- --host=0.0.0.0
|
||||||
- --wallet.totalAccounts=13
|
- --accounts=13
|
||||||
- --chain.chainId=1337
|
- --chain-id=1337
|
||||||
- --chain.asyncRequestProcessing=false
|
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8545
|
- containerPort: 8545
|
||||||
name: rpc
|
name: rpc
|
||||||
|
@ -64,11 +61,5 @@ spec:
|
||||||
initialDelaySeconds: 90
|
initialDelaySeconds: 90
|
||||||
tcpSocket:
|
tcpSocket:
|
||||||
port: 2000
|
port: 2000
|
||||||
- name: mine
|
|
||||||
image: eth-node
|
|
||||||
command:
|
|
||||||
- /bin/sh
|
|
||||||
- -c
|
|
||||||
- "cd ../../ethereum && npx truffle exec mine.js"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -32,19 +32,16 @@ spec:
|
||||||
spec:
|
spec:
|
||||||
terminationGracePeriodSeconds: 1
|
terminationGracePeriodSeconds: 1
|
||||||
containers:
|
containers:
|
||||||
- name: ganache
|
- name: anvil
|
||||||
image: eth-node
|
image: eth-node
|
||||||
command:
|
command:
|
||||||
- npx
|
- anvil
|
||||||
- ganache-cli
|
- --silent
|
||||||
- --logging.quiet
|
- --mnemonic=myth like bonus scare over problem client lizard pioneer submit female collect
|
||||||
- --wallet.defaultBalance=10000
|
- --block-time=1
|
||||||
- --wallet.deterministic
|
|
||||||
- --chain.time="1970-01-01T00:00:00+00:00"
|
|
||||||
- --host=0.0.0.0
|
- --host=0.0.0.0
|
||||||
- --wallet.totalAccounts=13
|
- --accounts=13
|
||||||
- --chain.chainId=1397
|
- --chain-id=1397
|
||||||
- --chain.asyncRequestProcessing=false
|
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8545
|
- containerPort: 8545
|
||||||
name: rpc
|
name: rpc
|
||||||
|
@ -65,9 +62,3 @@ spec:
|
||||||
initialDelaySeconds: 90
|
initialDelaySeconds: 90
|
||||||
tcpSocket:
|
tcpSocket:
|
||||||
port: 2000
|
port: 2000
|
||||||
- name: mine
|
|
||||||
image: eth-node
|
|
||||||
command:
|
|
||||||
- /bin/sh
|
|
||||||
- -c
|
|
||||||
- "cd ../../ethereum && npx truffle exec mine.js"
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ RUN $HOME/.foundry/bin/foundryup
|
||||||
RUN ls $HOME/.foundry/bin
|
RUN ls $HOME/.foundry/bin
|
||||||
|
|
||||||
# Run as user, otherwise, npx explodes.
|
# Run as user, otherwise, npx explodes.
|
||||||
|
RUN mv /root/.foundry/bin/anvil /bin/anvil
|
||||||
RUN mv /root/.foundry/bin/forge /bin/forge
|
RUN mv /root/.foundry/bin/forge /bin/forge
|
||||||
USER 1000
|
USER 1000
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# This script copies package{-lock}.json from a running container.
|
|
||||||
set -e
|
|
||||||
|
|
||||||
kubectl cp -c ganache eth-devnet-0:package.json package.json
|
|
||||||
kubectl cp -c ganache eth-devnet-0:package-lock.json package-lock.json
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
This script advances Ganache network state. It runs as a sidecar pod alongside the devnet and
|
|
||||||
ensures that manual token transfers triggered through the web UI will be able to be confirmed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
advanceBlock = () => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
web3.currentProvider.send({
|
|
||||||
jsonrpc: "2.0",
|
|
||||||
method: "evm_mine",
|
|
||||||
id: new Date().getTime()
|
|
||||||
}, (err, result) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err);
|
|
||||||
}
|
|
||||||
const newBlockHash = web3.eth.getBlock('latest').hash;
|
|
||||||
|
|
||||||
return resolve(newBlockHash)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sleep(ms) {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function(callback) {
|
|
||||||
const fn = async () => {
|
|
||||||
while (true) {
|
|
||||||
await advanceBlock();
|
|
||||||
await sleep(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn().catch(reason => console.error(reason))
|
|
||||||
}
|
|
|
@ -19,6 +19,9 @@ type (
|
||||||
// maxCacheSize is used to trim the cache.
|
// maxCacheSize is used to trim the cache.
|
||||||
maxCacheSize int
|
maxCacheSize int
|
||||||
|
|
||||||
|
// unsafeDevMode is used to suppress warnings in dev mode.
|
||||||
|
unsafeDevMode bool
|
||||||
|
|
||||||
// mutex is used to protect the cache.
|
// mutex is used to protect the cache.
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
@ -32,10 +35,11 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewBlocksByTimestamp creates an empty cache of blocks by timestamp.
|
// NewBlocksByTimestamp creates an empty cache of blocks by timestamp.
|
||||||
func NewBlocksByTimestamp(maxCacheSize int) *BlocksByTimestamp {
|
func NewBlocksByTimestamp(maxCacheSize int, unsafeDevMode bool) *BlocksByTimestamp {
|
||||||
return &BlocksByTimestamp{
|
return &BlocksByTimestamp{
|
||||||
cache: Blocks{},
|
cache: Blocks{},
|
||||||
maxCacheSize: maxCacheSize,
|
maxCacheSize: maxCacheSize,
|
||||||
|
unsafeDevMode: unsafeDevMode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,12 +59,15 @@ func (bts *BlocksByTimestamp) AddLatest(logger *zap.Logger, timestamp uint64, bl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Warn("rollback detected in timestamp cache",
|
// Anvil trips this when using `anvil_mine`
|
||||||
zap.Uint64("oldLatestBlockNum", bts.cache[l-1].BlockNum),
|
if !bts.unsafeDevMode {
|
||||||
zap.Uint64("oldLatestTimestamp", bts.cache[l-1].Timestamp),
|
logger.Warn("rollback detected in timestamp cache",
|
||||||
zap.Uint64("newLatestBlockNum", blockNum),
|
zap.Uint64("oldLatestBlockNum", bts.cache[l-1].BlockNum),
|
||||||
zap.Uint64("newLatestTimestamp", timestamp),
|
zap.Uint64("oldLatestTimestamp", bts.cache[l-1].Timestamp),
|
||||||
)
|
zap.Uint64("newLatestBlockNum", blockNum),
|
||||||
|
zap.Uint64("newLatestTimestamp", timestamp),
|
||||||
|
)
|
||||||
|
}
|
||||||
bts.cache = bts.cache[:idx+1]
|
bts.cache = bts.cache[:idx+1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ func cacheIsValid(t *testing.T, bts *BlocksByTimestamp) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBlocksByTimestamp_TestCacheIsValid(t *testing.T) {
|
func TestBlocksByTimestamp_TestCacheIsValid(t *testing.T) {
|
||||||
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS)
|
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
|
||||||
|
|
||||||
// Empty cache is valid.
|
// Empty cache is valid.
|
||||||
assert.True(t, cacheIsValid(t, bts))
|
assert.True(t, cacheIsValid(t, bts))
|
||||||
|
@ -61,7 +61,7 @@ func TestBlocksByTimestamp_TestCacheIsValid(t *testing.T) {
|
||||||
|
|
||||||
func TestBlocksByTimestamp_AddLatest(t *testing.T) {
|
func TestBlocksByTimestamp_AddLatest(t *testing.T) {
|
||||||
logger := zap.NewNop()
|
logger := zap.NewNop()
|
||||||
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS)
|
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
|
||||||
|
|
||||||
bts.AddLatest(logger, 1698621628, 420)
|
bts.AddLatest(logger, 1698621628, 420)
|
||||||
bts.AddLatest(logger, 1698621628, 421)
|
bts.AddLatest(logger, 1698621628, 421)
|
||||||
|
@ -89,7 +89,7 @@ func TestBlocksByTimestamp_AddLatest(t *testing.T) {
|
||||||
|
|
||||||
func TestBlocksByTimestamp_AddLatestRollbackEverything(t *testing.T) {
|
func TestBlocksByTimestamp_AddLatestRollbackEverything(t *testing.T) {
|
||||||
logger := zap.NewNop()
|
logger := zap.NewNop()
|
||||||
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS)
|
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
|
||||||
|
|
||||||
bts.AddLatest(logger, 1698621628, 420)
|
bts.AddLatest(logger, 1698621628, 420)
|
||||||
require.Equal(t, 1, len(bts.cache))
|
require.Equal(t, 1, len(bts.cache))
|
||||||
|
@ -138,7 +138,7 @@ func TestBlocksByTimestamp_AddLatestRollbackEverything(t *testing.T) {
|
||||||
|
|
||||||
func TestBlocksByTimestamp_AddLatestShouldTrimTheCache(t *testing.T) {
|
func TestBlocksByTimestamp_AddLatestShouldTrimTheCache(t *testing.T) {
|
||||||
logger := zap.NewNop()
|
logger := zap.NewNop()
|
||||||
bts := NewBlocksByTimestamp(5)
|
bts := NewBlocksByTimestamp(5, false)
|
||||||
|
|
||||||
bts.AddLatest(logger, 1698621628, 420)
|
bts.AddLatest(logger, 1698621628, 420)
|
||||||
bts.AddLatest(logger, 1698621628, 421)
|
bts.AddLatest(logger, 1698621628, 421)
|
||||||
|
@ -161,7 +161,7 @@ func TestBlocksByTimestamp_AddLatestShouldTrimTheCache(t *testing.T) {
|
||||||
|
|
||||||
func TestBlocksByTimestamp_AddBatch(t *testing.T) {
|
func TestBlocksByTimestamp_AddBatch(t *testing.T) {
|
||||||
logger := zap.NewNop()
|
logger := zap.NewNop()
|
||||||
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS)
|
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
|
||||||
|
|
||||||
// First create a cache with some gaps in it.
|
// First create a cache with some gaps in it.
|
||||||
bts.AddLatest(logger, 1698621628, 420)
|
bts.AddLatest(logger, 1698621628, 420)
|
||||||
|
@ -192,7 +192,7 @@ func TestBlocksByTimestamp_AddBatch(t *testing.T) {
|
||||||
|
|
||||||
func TestBlocksByTimestamp_AddBatchShouldTrim(t *testing.T) {
|
func TestBlocksByTimestamp_AddBatchShouldTrim(t *testing.T) {
|
||||||
logger := zap.NewNop()
|
logger := zap.NewNop()
|
||||||
bts := NewBlocksByTimestamp(8)
|
bts := NewBlocksByTimestamp(8, false)
|
||||||
|
|
||||||
// First create a cache with some gaps in it.
|
// First create a cache with some gaps in it.
|
||||||
bts.AddLatest(logger, 1698621628, 420)
|
bts.AddLatest(logger, 1698621628, 420)
|
||||||
|
@ -249,7 +249,7 @@ func TestBlocksByTimestamp_SearchForTimestamp(t *testing.T) {
|
||||||
|
|
||||||
func TestBlocksByTimestamp_LookUp(t *testing.T) {
|
func TestBlocksByTimestamp_LookUp(t *testing.T) {
|
||||||
logger := zap.NewNop()
|
logger := zap.NewNop()
|
||||||
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS)
|
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
|
||||||
|
|
||||||
// Empty cache.
|
// Empty cache.
|
||||||
prev, next, found := bts.LookUp(1698621627)
|
prev, next, found := bts.LookUp(1698621627)
|
||||||
|
|
|
@ -260,7 +260,7 @@ func (w *Watcher) Run(parentCtx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.ccqConfig.TimestampCacheSupported {
|
if w.ccqConfig.TimestampCacheSupported {
|
||||||
w.ccqTimestampCache = NewBlocksByTimestamp(BTS_MAX_BLOCKS)
|
w.ccqTimestampCache = NewBlocksByTimestamp(BTS_MAX_BLOCKS, w.unsafeDevMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
errC := make(chan error)
|
errC := make(chan error)
|
||||||
|
@ -702,7 +702,6 @@ func (w *Watcher) getFinality(ctx context.Context) (bool, bool, error) {
|
||||||
finalized := false
|
finalized := false
|
||||||
safe := false
|
safe := false
|
||||||
if w.unsafeDevMode {
|
if w.unsafeDevMode {
|
||||||
// Devnet supports finalized and safe (although they returns the same value as latest).
|
|
||||||
finalized = true
|
finalized = true
|
||||||
safe = true
|
safe = true
|
||||||
} else if w.chainID == vaa.ChainIDAcala ||
|
} else if w.chainID == vaa.ChainIDAcala ||
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
process.env.CI = true;
|
process.env.CI = true;
|
||||||
|
|
||||||
|
const warn = console.warn;
|
||||||
|
console.warn = function (x) {
|
||||||
|
if (
|
||||||
|
x !==
|
||||||
|
"bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)"
|
||||||
|
) {
|
||||||
|
warn(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {};
|
module.exports = {};
|
||||||
|
|
|
@ -1,34 +1,26 @@
|
||||||
import {
|
import { beforeAll, describe, expect, jest, test } from "@jest/globals";
|
||||||
afterAll,
|
import axios, { AxiosResponse } from "axios";
|
||||||
beforeAll,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
jest,
|
|
||||||
test,
|
|
||||||
} from "@jest/globals";
|
|
||||||
import Web3, { ETH_DATA_FORMAT } from "web3";
|
import Web3, { ETH_DATA_FORMAT } from "web3";
|
||||||
import axios from "axios";
|
|
||||||
import { AxiosResponse } from "axios";
|
|
||||||
import {
|
import {
|
||||||
ChainQueryType,
|
ChainQueryType,
|
||||||
|
EthCallByTimestampQueryRequest,
|
||||||
|
EthCallByTimestampQueryResponse,
|
||||||
EthCallData,
|
EthCallData,
|
||||||
EthCallQueryRequest,
|
EthCallQueryRequest,
|
||||||
EthCallByTimestampQueryRequest,
|
EthCallQueryResponse,
|
||||||
EthCallWithFinalityQueryRequest,
|
EthCallWithFinalityQueryRequest,
|
||||||
|
EthCallWithFinalityQueryResponse,
|
||||||
PerChainQueryRequest,
|
PerChainQueryRequest,
|
||||||
QueryRequest,
|
QueryRequest,
|
||||||
sign,
|
|
||||||
QueryResponse,
|
QueryResponse,
|
||||||
EthCallQueryResponse,
|
sign,
|
||||||
EthCallByTimestampQueryResponse,
|
|
||||||
EthCallWithFinalityQueryResponse,
|
|
||||||
} from "..";
|
} from "..";
|
||||||
|
|
||||||
jest.setTimeout(125000);
|
jest.setTimeout(125000);
|
||||||
|
|
||||||
const CI = process.env.CI;
|
const CI = process.env.CI;
|
||||||
const ENV = "DEVNET";
|
const ENV = "DEVNET";
|
||||||
const ETH_NODE_URL = CI ? "ws://eth-devnet:8545" : "ws://localhost:8545";
|
const ETH_NODE_URL = CI ? "http://eth-devnet:8545" : "http://localhost:8545";
|
||||||
|
|
||||||
const SERVER_URL = CI ? "http://query-server:" : "http://localhost:";
|
const SERVER_URL = CI ? "http://query-server:" : "http://localhost:";
|
||||||
const CCQ_SERVER_URL = SERVER_URL + "6069/v1";
|
const CCQ_SERVER_URL = SERVER_URL + "6069/v1";
|
||||||
|
@ -44,10 +36,6 @@ beforeAll(() => {
|
||||||
web3 = new Web3(ETH_NODE_URL);
|
web3 = new Web3(ETH_NODE_URL);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
web3.provider?.disconnect();
|
|
||||||
});
|
|
||||||
|
|
||||||
function createTestEthCallData(
|
function createTestEthCallData(
|
||||||
to: string,
|
to: string,
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -162,7 +150,7 @@ describe("eth call", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const ecr = queryResponse.responses[0].response as EthCallQueryResponse;
|
const ecr = queryResponse.responses[0].response as EthCallQueryResponse;
|
||||||
expect(ecr.blockNumber).toEqual(BigInt(blockNumber));
|
expect(ecr.blockNumber.toString()).toEqual(BigInt(blockNumber).toString());
|
||||||
expect(ecr.blockHash).toEqual(
|
expect(ecr.blockHash).toEqual(
|
||||||
(await web3.eth.getBlock(BigInt(blockNumber))).hash
|
(await web3.eth.getBlock(BigInt(blockNumber))).hash
|
||||||
);
|
);
|
||||||
|
@ -176,8 +164,7 @@ describe("eth call", () => {
|
||||||
"0x0000000000000000000000000000000000000000000000000000000000000012"
|
"0x0000000000000000000000000000000000000000000000000000000000000012"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// TODO: This test works in Goerli testnet but not devnet. Try it again after PR #3395 lands.
|
test("get block by hash should work", async () => {
|
||||||
test.skip("get block by hash should work", async () => {
|
|
||||||
const nameCallData = createTestEthCallData(WETH_ADDRESS, "name", "string");
|
const nameCallData = createTestEthCallData(WETH_ADDRESS, "name", "string");
|
||||||
const decimalsCallData = createTestEthCallData(
|
const decimalsCallData = createTestEthCallData(
|
||||||
WETH_ADDRESS,
|
WETH_ADDRESS,
|
||||||
|
@ -461,11 +448,15 @@ describe("eth call", () => {
|
||||||
|
|
||||||
const ecr = queryResponse.responses[0]
|
const ecr = queryResponse.responses[0]
|
||||||
.response as EthCallByTimestampQueryResponse;
|
.response as EthCallByTimestampQueryResponse;
|
||||||
expect(ecr.targetBlockNumber).toEqual(BigInt(targetBlockNumber));
|
expect(ecr.targetBlockNumber.toString()).toEqual(
|
||||||
|
BigInt(targetBlockNumber).toString()
|
||||||
|
);
|
||||||
expect(ecr.targetBlockHash).toEqual(
|
expect(ecr.targetBlockHash).toEqual(
|
||||||
(await web3.eth.getBlock(BigInt(targetBlockNumber))).hash
|
(await web3.eth.getBlock(BigInt(targetBlockNumber))).hash
|
||||||
);
|
);
|
||||||
expect(ecr.followingBlockNumber).toEqual(BigInt(followingBlockNumber));
|
expect(ecr.followingBlockNumber.toString()).toEqual(
|
||||||
|
BigInt(followingBlockNumber).toString()
|
||||||
|
);
|
||||||
expect(ecr.followingBlockHash).toEqual(
|
expect(ecr.followingBlockHash).toEqual(
|
||||||
(await web3.eth.getBlock(BigInt(followingBlockNumber))).hash
|
(await web3.eth.getBlock(BigInt(followingBlockNumber))).hash
|
||||||
);
|
);
|
||||||
|
@ -523,11 +514,15 @@ describe("eth call", () => {
|
||||||
|
|
||||||
const ecr = queryResponse.responses[0]
|
const ecr = queryResponse.responses[0]
|
||||||
.response as EthCallByTimestampQueryResponse;
|
.response as EthCallByTimestampQueryResponse;
|
||||||
expect(ecr.targetBlockNumber).toEqual(BigInt(targetBlockNumber));
|
expect(ecr.targetBlockNumber.toString()).toEqual(
|
||||||
|
BigInt(targetBlockNumber).toString()
|
||||||
|
);
|
||||||
expect(ecr.targetBlockHash).toEqual(
|
expect(ecr.targetBlockHash).toEqual(
|
||||||
(await web3.eth.getBlock(BigInt(targetBlockNumber))).hash
|
(await web3.eth.getBlock(BigInt(targetBlockNumber))).hash
|
||||||
);
|
);
|
||||||
expect(ecr.followingBlockNumber).toEqual(BigInt(followingBlockNumber));
|
expect(ecr.followingBlockNumber.toString()).toEqual(
|
||||||
|
BigInt(followingBlockNumber).toString()
|
||||||
|
);
|
||||||
expect(ecr.followingBlockHash).toEqual(
|
expect(ecr.followingBlockHash).toEqual(
|
||||||
(await web3.eth.getBlock(BigInt(followingBlockNumber))).hash
|
(await web3.eth.getBlock(BigInt(followingBlockNumber))).hash
|
||||||
);
|
);
|
||||||
|
@ -703,9 +698,9 @@ describe("eth call", () => {
|
||||||
"decimals",
|
"decimals",
|
||||||
"uint8"
|
"uint8"
|
||||||
);
|
);
|
||||||
// Jump into the future a bit so the watcher has to wait for finality.
|
const blockNumber = Number(
|
||||||
const blockNumber =
|
(await web3.eth.getBlock("finalized", false, ETH_DATA_FORMAT)).number
|
||||||
Number(await web3.eth.getBlockNumber(ETH_DATA_FORMAT)) + 10;
|
);
|
||||||
const ethCall = new EthCallWithFinalityQueryRequest(
|
const ethCall = new EthCallWithFinalityQueryRequest(
|
||||||
blockNumber.toString(16),
|
blockNumber.toString(16),
|
||||||
"finalized",
|
"finalized",
|
||||||
|
@ -740,7 +735,7 @@ describe("eth call", () => {
|
||||||
|
|
||||||
const ecr = queryResponse.responses[0]
|
const ecr = queryResponse.responses[0]
|
||||||
.response as EthCallWithFinalityQueryResponse;
|
.response as EthCallWithFinalityQueryResponse;
|
||||||
expect(ecr.blockNumber).toEqual(BigInt(blockNumber));
|
expect(ecr.blockNumber.toString()).toEqual(BigInt(blockNumber).toString());
|
||||||
expect(ecr.blockHash).toEqual(
|
expect(ecr.blockHash).toEqual(
|
||||||
(await web3.eth.getBlock(BigInt(blockNumber))).hash
|
(await web3.eth.getBlock(BigInt(blockNumber))).hash
|
||||||
);
|
);
|
||||||
|
@ -881,7 +876,9 @@ describe("eth call", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const ecr = queryResponse.responses[0].response as EthCallQueryResponse;
|
const ecr = queryResponse.responses[0].response as EthCallQueryResponse;
|
||||||
expect(ecr.blockNumber).toEqual(BigInt(blockNumber));
|
expect(ecr.blockNumber.toString()).toEqual(
|
||||||
|
BigInt(blockNumber).toString()
|
||||||
|
);
|
||||||
expect(ecr.blockHash).toEqual(
|
expect(ecr.blockHash).toEqual(
|
||||||
(await web3.eth.getBlock(BigInt(blockNumber))).hash
|
(await web3.eth.getBlock(BigInt(blockNumber))).hash
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,28 @@
|
||||||
process.env.CI = true;
|
process.env.CI = true;
|
||||||
|
|
||||||
|
const info = console.info;
|
||||||
|
console.info = function (x) {
|
||||||
|
if (x !== "secp256k1 unavailable, reverting to browser version") {
|
||||||
|
info(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const warn = console.warn;
|
||||||
|
console.warn = function (x) {
|
||||||
|
if (
|
||||||
|
x !==
|
||||||
|
"bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)" &&
|
||||||
|
!(
|
||||||
|
typeof x === "object" &&
|
||||||
|
x
|
||||||
|
.toString()
|
||||||
|
.includes(
|
||||||
|
"RPC Validation Error: The response returned from RPC server does not match the TypeScript definition. This is likely because the SDK version is not compatible with the RPC server."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
warn(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default {};
|
export default {};
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
|
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
|
||||||
"testPathIgnorePatterns": ["__tests__/utils"],
|
"testPathIgnorePatterns": ["__tests__/utils"],
|
||||||
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
|
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
|
||||||
"testTimeout": 60000
|
"testTimeout": 300000
|
||||||
}
|
}
|
|
@ -18,10 +18,10 @@
|
||||||
"build-lib": "tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && node scripts/copyEthersTypes.js",
|
"build-lib": "tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && node scripts/copyEthersTypes.js",
|
||||||
"build-all": "npm run build-deps && npm run build-lib",
|
"build-all": "npm run build-deps && npm run build-lib",
|
||||||
"docs": "typedoc src/index.ts",
|
"docs": "typedoc src/index.ts",
|
||||||
"test": "DEV=true NETWORK=DEVNET jest --config jestconfig.json --verbose",
|
"test": "DEV=true NETWORK=DEVNET jest --verbose",
|
||||||
"test-ci": "NETWORK=DEVNET NEAR_NO_LOGS=true jest --config jestconfig.json --verbose --setupFiles ./ci-config.js --forceExit",
|
"test-ci": "NETWORK=DEVNET NEAR_NO_LOGS=true jest --verbose --setupFiles ./ci-config.js --forceExit",
|
||||||
"test-relayer-mainnet": "ENV=mainnet NETWORK=MAINNET npx jest --config jestconfig.json --verbose ./src/relayer/",
|
"test-relayer-mainnet": "ENV=mainnet NETWORK=MAINNET npx jest --verbose ./src/relayer/",
|
||||||
"test-relayer-testnet": "ENV=testnet NETWORK=TESTNET npx jest --config jestconfig.json --verbose ./src/relayer/",
|
"test-relayer-testnet": "ENV=testnet NETWORK=TESTNET npx jest --verbose ./src/relayer/",
|
||||||
"build": "npm run build-all",
|
"build": "npm run build-all",
|
||||||
"format": "echo \"disabled: prettier --write \"src/**/*.ts\"\"",
|
"format": "echo \"disabled: prettier --write \"src/**/*.ts\"\"",
|
||||||
"lint": "tslint -p tsconfig.json",
|
"lint": "tslint -p tsconfig.json",
|
||||||
|
|
|
@ -27,8 +27,6 @@ import { PopulateData, TmplSig } from "../TmplSig";
|
||||||
const CORE_ID = BigInt(1004);
|
const CORE_ID = BigInt(1004);
|
||||||
const TOKEN_BRIDGE_ID = BigInt(1006);
|
const TOKEN_BRIDGE_ID = BigInt(1006);
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
describe("Unit Tests", () => {
|
describe("Unit Tests", () => {
|
||||||
describe("Algorand unit tests", () => {
|
describe("Algorand unit tests", () => {
|
||||||
test("Test TmplSig populate()", (done) => {
|
test("Test TmplSig populate()", (done) => {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
getSignedVAABySequence,
|
getSignedVAABySequence,
|
||||||
waitForTerraExecution,
|
waitForTerraExecution,
|
||||||
} from "../../token_bridge/__tests__/utils/helpers";
|
} from "../../token_bridge/__tests__/utils/helpers";
|
||||||
import { CHAIN_ID_SEI, CHAIN_ID_TERRA2 } from "../../utils/consts";
|
import { CHAIN_ID_SEI } from "../../utils/consts";
|
||||||
|
|
||||||
const TERRA2_PRIVATE_KEY_4 =
|
const TERRA2_PRIVATE_KEY_4 =
|
||||||
"bounce success option birth apple portion aunt rural episode solution hockey pencil lend session cause hedgehog slender journey system canvas decorate razor catch empty";
|
"bounce success option birth apple portion aunt rural episode solution hockey pencil lend session cause hedgehog slender journey system canvas decorate razor catch empty";
|
||||||
|
@ -58,7 +58,6 @@ const terraBroadcastTxAndGetSignedVaa = async (
|
||||||
if (!txSequence) {
|
if (!txSequence) {
|
||||||
throw new Error("tx sequence not found");
|
throw new Error("tx sequence not found");
|
||||||
}
|
}
|
||||||
console.log(`${CHAIN_ID_SEI}/${emitter}/${txSequence}`);
|
|
||||||
return await getSignedVAABySequence(CHAIN_ID_SEI, txSequence, emitter);
|
return await getSignedVAABySequence(CHAIN_ID_SEI, txSequence, emitter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,6 +78,5 @@ describe("IBC Watcher Integration Tests", () => {
|
||||||
terraWallet,
|
terraWallet,
|
||||||
await getEmitterAddressTerra(terraWalletAddress)
|
await getEmitterAddressTerra(terraWalletAddress)
|
||||||
);
|
);
|
||||||
console.log(postedVaa);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,8 +55,6 @@ import {
|
||||||
getSignedVaaSolana,
|
getSignedVaaSolana,
|
||||||
} from "./utils/getSignedVaa";
|
} from "./utils/getSignedVaa";
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
const APTOS_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.aptos.nft_bridge;
|
const APTOS_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.aptos.nft_bridge;
|
||||||
const ETH_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.nft_bridge;
|
const ETH_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.nft_bridge;
|
||||||
const SOLANA_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.solana.nft_bridge;
|
const SOLANA_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.solana.nft_bridge;
|
||||||
|
@ -69,7 +67,7 @@ let faucet: FaucetClient;
|
||||||
|
|
||||||
// ethereum setup
|
// ethereum setup
|
||||||
const web3 = new Web3(ETH_NODE_URL);
|
const web3 = new Web3(ETH_NODE_URL);
|
||||||
const ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const ethProvider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY8, ethProvider);
|
const ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY8, ethProvider);
|
||||||
|
|
||||||
// solana setup
|
// solana setup
|
||||||
|
@ -86,7 +84,6 @@ beforeEach(async () => {
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
(web3.currentProvider as any).disconnect();
|
(web3.currentProvider as any).disconnect();
|
||||||
await ethProvider.destroy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Aptos NFT SDK tests", () => {
|
describe("Aptos NFT SDK tests", () => {
|
||||||
|
@ -112,6 +109,7 @@ describe("Aptos NFT SDK tests", () => {
|
||||||
CHAIN_ID_APTOS,
|
CHAIN_ID_APTOS,
|
||||||
aptosAccount.address().toUint8Array()
|
aptosAccount.address().toUint8Array()
|
||||||
);
|
);
|
||||||
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
|
|
||||||
// observe tx and get vaa
|
// observe tx and get vaa
|
||||||
const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx);
|
const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx);
|
||||||
|
@ -313,6 +311,7 @@ describe("Aptos NFT SDK tests", () => {
|
||||||
tryNativeToUint8Array(aptosAccount.address().toString(), CHAIN_ID_APTOS)
|
tryNativeToUint8Array(aptosAccount.address().toString(), CHAIN_ID_APTOS)
|
||||||
);
|
);
|
||||||
expect(ethTransferTx.status).toBe(1);
|
expect(ethTransferTx.status).toBe(1);
|
||||||
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
|
|
||||||
// observe tx and get vaa
|
// observe tx and get vaa
|
||||||
const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx);
|
const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx);
|
||||||
|
@ -455,6 +454,7 @@ describe("Aptos NFT SDK tests", () => {
|
||||||
CHAIN_ID_APTOS,
|
CHAIN_ID_APTOS,
|
||||||
aptosAccount.address().toUint8Array()
|
aptosAccount.address().toUint8Array()
|
||||||
);
|
);
|
||||||
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
|
|
||||||
// observe txs and get vaas
|
// observe txs and get vaas
|
||||||
const ethTransferVaa1 = await getSignedVaaEthereum(ethTransferTx1);
|
const ethTransferVaa1 = await getSignedVaaEthereum(ethTransferTx1);
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
import {
|
import { beforeEach, describe, expect, jest, test } from "@jest/globals";
|
||||||
afterEach,
|
|
||||||
beforeEach,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
jest,
|
|
||||||
test,
|
|
||||||
} from "@jest/globals";
|
|
||||||
import { getAssociatedTokenAddress } from "@solana/spl-token";
|
import { getAssociatedTokenAddress } from "@solana/spl-token";
|
||||||
import {
|
import {
|
||||||
Connection,
|
Connection,
|
||||||
|
@ -16,10 +9,10 @@ import {
|
||||||
import { BigNumberish, ethers } from "ethers";
|
import { BigNumberish, ethers } from "ethers";
|
||||||
import Web3 from "web3";
|
import Web3 from "web3";
|
||||||
import {
|
import {
|
||||||
ChainId,
|
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
|
ChainId,
|
||||||
nft_bridge,
|
nft_bridge,
|
||||||
} from "../..";
|
} from "../..";
|
||||||
import { postVaaSolanaWithRetry } from "../../solana";
|
import { postVaaSolanaWithRetry } from "../../solana";
|
||||||
|
@ -34,11 +27,9 @@ import {
|
||||||
} from "./utils/consts";
|
} from "./utils/consts";
|
||||||
import { getSignedVaaEthereum, getSignedVaaSolana } from "./utils/getSignedVaa";
|
import { getSignedVaaEthereum, getSignedVaaSolana } from "./utils/getSignedVaa";
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
// ethereum setup
|
// ethereum setup
|
||||||
const web3 = new Web3(ETH_NODE_URL);
|
const web3 = new Web3(ETH_NODE_URL);
|
||||||
let provider: ethers.providers.WebSocketProvider;
|
let provider: ethers.providers.JsonRpcProvider;
|
||||||
let signer: ethers.Wallet;
|
let signer: ethers.Wallet;
|
||||||
|
|
||||||
// solana setup
|
// solana setup
|
||||||
|
@ -47,14 +38,10 @@ const keypair = Keypair.fromSecretKey(SOLANA_PRIVATE_KEY);
|
||||||
const payerAddress = keypair.publicKey.toString();
|
const payerAddress = keypair.publicKey.toString();
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider); // corresponds to accounts[1]
|
signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider); // corresponds to accounts[1]
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
provider.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Integration Tests", () => {
|
describe("Integration Tests", () => {
|
||||||
test("Send Solana SPL to Ethereum and back", (done) => {
|
test("Send Solana SPL to Ethereum and back", (done) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@ -93,6 +80,7 @@ describe("Integration Tests", () => {
|
||||||
fromAddress.toString(),
|
fromAddress.toString(),
|
||||||
CHAIN_ID_SOLANA
|
CHAIN_ID_SOLANA
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
signedVAA = await getSignedVaaEthereum(transaction3);
|
signedVAA = await getSignedVaaEthereum(transaction3);
|
||||||
|
|
||||||
const { name, symbol } = parseNftTransferVaa(signedVAA);
|
const { name, symbol } = parseNftTransferVaa(signedVAA);
|
||||||
|
|
|
@ -4,7 +4,9 @@ import { Connection, PublicKey } from "@solana/web3.js";
|
||||||
const ci = !!process.env.CI;
|
const ci = !!process.env.CI;
|
||||||
|
|
||||||
// see devnet.md
|
// see devnet.md
|
||||||
export const ETH_NODE_URL = ci ? "ws://eth-devnet:8545" : "ws://localhost:8545";
|
export const ETH_NODE_URL = ci
|
||||||
|
? "http://eth-devnet:8545"
|
||||||
|
: "http://localhost:8545";
|
||||||
export const ETH_PRIVATE_KEY =
|
export const ETH_PRIVATE_KEY =
|
||||||
"0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1"; // account 1
|
"0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1"; // account 1
|
||||||
export const ETH_PRIVATE_KEY8 =
|
export const ETH_PRIVATE_KEY8 =
|
||||||
|
|
|
@ -1,34 +1,33 @@
|
||||||
|
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||||
import { describe, expect, test } from "@jest/globals";
|
import { describe, expect, test } from "@jest/globals";
|
||||||
import { ContractReceipt, ethers } from "ethers";
|
import { ContractReceipt, ethers } from "ethers";
|
||||||
import {
|
import {
|
||||||
getNetwork,
|
|
||||||
isCI,
|
|
||||||
waitForRelay,
|
|
||||||
PRIVATE_KEY,
|
|
||||||
getGuardianRPC,
|
|
||||||
GUARDIAN_KEYS,
|
|
||||||
GUARDIAN_SET_INDEX,
|
|
||||||
GOVERNANCE_EMITTER_ADDRESS,
|
|
||||||
getArbitraryBytes32,
|
|
||||||
} from "./utils/utils";
|
|
||||||
import { getAddressInfo } from "../consts";
|
|
||||||
import { getDefaultProvider } from "../relayer/helpers";
|
|
||||||
import {
|
|
||||||
relayer,
|
|
||||||
ethers_contracts,
|
|
||||||
ethers_relayer_contracts,
|
|
||||||
tryNativeToUint8Array,
|
|
||||||
ChainId,
|
|
||||||
CHAINS,
|
CHAINS,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
|
ChainId,
|
||||||
ChainName,
|
ChainName,
|
||||||
Network,
|
Network,
|
||||||
|
ethers_relayer_contracts,
|
||||||
|
relayer,
|
||||||
|
tryNativeToUint8Array,
|
||||||
} from "../../../";
|
} from "../../../";
|
||||||
import { GovernanceEmitter, MockGuardians } from "../../../src/mock";
|
import { GovernanceEmitter, MockGuardians } from "../../../src/mock";
|
||||||
import { Implementation__factory } from "../../ethers-contracts";
|
import { Implementation__factory } from "../../ethers-contracts";
|
||||||
|
import { getAddressInfo } from "../consts";
|
||||||
import { manualDelivery } from "../relayer";
|
import { manualDelivery } from "../relayer";
|
||||||
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
import { getDefaultProvider } from "../relayer/helpers";
|
||||||
import { packEVMExecutionInfoV1 } from "../structs";
|
import { packEVMExecutionInfoV1 } from "../structs";
|
||||||
|
import {
|
||||||
|
GOVERNANCE_EMITTER_ADDRESS,
|
||||||
|
GUARDIAN_KEYS,
|
||||||
|
GUARDIAN_SET_INDEX,
|
||||||
|
PRIVATE_KEY,
|
||||||
|
getArbitraryBytes32,
|
||||||
|
getGuardianRPC,
|
||||||
|
getNetwork,
|
||||||
|
isCI,
|
||||||
|
waitForRelay,
|
||||||
|
} from "./utils/utils";
|
||||||
|
|
||||||
const network: Network = getNetwork();
|
const network: Network = getNetwork();
|
||||||
const ci: boolean = isCI();
|
const ci: boolean = isCI();
|
||||||
|
@ -42,7 +41,7 @@ const testIfNotDevnet = () => (network != "DEVNET" ? test : test.skip);
|
||||||
type TestChain = {
|
type TestChain = {
|
||||||
chainId: ChainId;
|
chainId: ChainId;
|
||||||
name: ChainName;
|
name: ChainName;
|
||||||
provider: ethers.providers.Provider;
|
provider: ethers.providers.StaticJsonRpcProvider;
|
||||||
wallet: ethers.Wallet;
|
wallet: ethers.Wallet;
|
||||||
wormholeRelayerAddress: string;
|
wormholeRelayerAddress: string;
|
||||||
mockIntegrationAddress: string;
|
mockIntegrationAddress: string;
|
||||||
|
@ -160,7 +159,7 @@ const testSend = async (
|
||||||
notEnoughValue ? TOO_LOW_GAS_LIMIT : REASONABLE_GAS_LIMIT,
|
notEnoughValue ? TOO_LOW_GAS_LIMIT : REASONABLE_GAS_LIMIT,
|
||||||
optionalParams
|
optionalParams
|
||||||
);
|
);
|
||||||
console.log(`Quoted gas delivery fee: ${value}`);
|
!ci && console.log(`Quoted gas delivery fee: ${value}`);
|
||||||
const tx = await source.mockIntegration.sendMessage(
|
const tx = await source.mockIntegration.sendMessage(
|
||||||
payload,
|
payload,
|
||||||
sendToSourceChain ? source.chainId : target.chainId,
|
sendToSourceChain ? source.chainId : target.chainId,
|
||||||
|
@ -168,9 +167,9 @@ const testSend = async (
|
||||||
0,
|
0,
|
||||||
{ value, gasLimit: REASONABLE_GAS_LIMIT }
|
{ value, gasLimit: REASONABLE_GAS_LIMIT }
|
||||||
);
|
);
|
||||||
console.log(`Sent delivery request! Transaction hash ${tx.hash}`);
|
!ci && console.log(`Sent delivery request! Transaction hash ${tx.hash}`);
|
||||||
await tx.wait();
|
await tx.wait();
|
||||||
console.log("Message confirmed!");
|
!ci && console.log("Message confirmed!");
|
||||||
|
|
||||||
return tx.wait();
|
return tx.wait();
|
||||||
};
|
};
|
||||||
|
@ -178,20 +177,20 @@ const testSend = async (
|
||||||
describe("Wormhole Relayer Tests", () => {
|
describe("Wormhole Relayer Tests", () => {
|
||||||
test("Executes a Delivery Success", async () => {
|
test("Executes a Delivery Success", async () => {
|
||||||
const arbitraryPayload = getArbitraryBytes32();
|
const arbitraryPayload = getArbitraryBytes32();
|
||||||
console.log(`Sent message: ${arbitraryPayload}`);
|
!ci && console.log(`Sent message: ${arbitraryPayload}`);
|
||||||
|
|
||||||
const rx = await testSend(arbitraryPayload);
|
const rx = await testSend(arbitraryPayload);
|
||||||
|
|
||||||
await waitForRelay();
|
await waitForRelay();
|
||||||
|
|
||||||
console.log("Checking if message was relayed");
|
!ci && console.log("Checking if message was relayed");
|
||||||
const message = await target.mockIntegration.getMessage();
|
const message = await target.mockIntegration.getMessage();
|
||||||
expect(message).toBe(arbitraryPayload);
|
expect(message).toBe(arbitraryPayload);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Executes a Delivery Success With Additional VAAs", async () => {
|
test("Executes a Delivery Success With Additional VAAs", async () => {
|
||||||
const arbitraryPayload = getArbitraryBytes32();
|
const arbitraryPayload = getArbitraryBytes32();
|
||||||
console.log(`Sent message: ${arbitraryPayload}`);
|
!ci && console.log(`Sent message: ${arbitraryPayload}`);
|
||||||
|
|
||||||
const wormhole = Implementation__factory.connect(
|
const wormhole = Implementation__factory.connect(
|
||||||
CONTRACTS[network][sourceChain].core || "",
|
CONTRACTS[network][sourceChain].core || "",
|
||||||
|
@ -207,7 +206,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
REASONABLE_GAS_LIMIT * 2,
|
REASONABLE_GAS_LIMIT * 2,
|
||||||
optionalParams
|
optionalParams
|
||||||
);
|
);
|
||||||
console.log(`Quoted gas delivery fee: ${value}`);
|
!ci && console.log(`Quoted gas delivery fee: ${value}`);
|
||||||
|
|
||||||
const tx = await source.mockIntegration.sendMessageWithAdditionalVaas(
|
const tx = await source.mockIntegration.sendMessageWithAdditionalVaas(
|
||||||
[],
|
[],
|
||||||
|
@ -224,13 +223,13 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
{ value }
|
{ value }
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`Sent tx hash: ${tx.hash}`);
|
!ci && console.log(`Sent tx hash: ${tx.hash}`);
|
||||||
|
|
||||||
const rx = await tx.wait();
|
const rx = await tx.wait();
|
||||||
|
|
||||||
await waitForRelay();
|
await waitForRelay();
|
||||||
|
|
||||||
console.log("Checking if message was relayed");
|
!ci && console.log("Checking if message was relayed");
|
||||||
const message = (await target.mockIntegration.getDeliveryData())
|
const message = (await target.mockIntegration.getDeliveryData())
|
||||||
.additionalVaas[0];
|
.additionalVaas[0];
|
||||||
const parsedMessage = await wormhole.parseVM(message);
|
const parsedMessage = await wormhole.parseVM(message);
|
||||||
|
@ -241,7 +240,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
"Executes a Delivery Success with manual delivery",
|
"Executes a Delivery Success with manual delivery",
|
||||||
async () => {
|
async () => {
|
||||||
const arbitraryPayload = getArbitraryBytes32();
|
const arbitraryPayload = getArbitraryBytes32();
|
||||||
console.log(`Sent message: ${arbitraryPayload}`);
|
!ci && console.log(`Sent message: ${arbitraryPayload}`);
|
||||||
|
|
||||||
const deliverySeq = await Implementation__factory.connect(
|
const deliverySeq = await Implementation__factory.connect(
|
||||||
CONTRACTS[network][sourceChain].core || "",
|
CONTRACTS[network][sourceChain].core || "",
|
||||||
|
@ -286,7 +285,10 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`Price: ${priceInfo.quote} of ${priceInfo.targetChain} wei`);
|
!ci &&
|
||||||
|
console.log(
|
||||||
|
`Price: ${priceInfo.quote} of ${priceInfo.targetChain} wei`
|
||||||
|
);
|
||||||
|
|
||||||
const deliveryRx = await manualDelivery(
|
const deliveryRx = await manualDelivery(
|
||||||
sourceChain,
|
sourceChain,
|
||||||
|
@ -310,9 +312,9 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
},
|
},
|
||||||
target.wallet
|
target.wallet
|
||||||
);
|
);
|
||||||
console.log("Manual delivery tx hash", deliveryRx.txHash);
|
!ci && console.log("Manual delivery tx hash", deliveryRx.txHash);
|
||||||
|
|
||||||
console.log("Checking if message was relayed");
|
!ci && console.log("Checking if message was relayed");
|
||||||
const message = await target.mockIntegration.getMessage();
|
const message = await target.mockIntegration.getMessage();
|
||||||
expect(message).toBe(arbitraryPayload);
|
expect(message).toBe(arbitraryPayload);
|
||||||
}
|
}
|
||||||
|
@ -330,14 +332,14 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
|
|
||||||
test("Executes a delivery with a Cross Chain Refund", async () => {
|
test("Executes a delivery with a Cross Chain Refund", async () => {
|
||||||
const arbitraryPayload = getArbitraryBytes32();
|
const arbitraryPayload = getArbitraryBytes32();
|
||||||
console.log(`Sent message: ${arbitraryPayload}`);
|
!ci && console.log(`Sent message: ${arbitraryPayload}`);
|
||||||
const value = await relayer.getPrice(
|
const value = await relayer.getPrice(
|
||||||
sourceChain,
|
sourceChain,
|
||||||
targetChain,
|
targetChain,
|
||||||
REASONABLE_GAS_LIMIT,
|
REASONABLE_GAS_LIMIT,
|
||||||
optionalParams
|
optionalParams
|
||||||
);
|
);
|
||||||
console.log(`Quoted gas delivery fee: ${value}`);
|
!ci && console.log(`Quoted gas delivery fee: ${value}`);
|
||||||
const startingBalance = await source.wallet.getBalance();
|
const startingBalance = await source.wallet.getBalance();
|
||||||
|
|
||||||
const tx = await relayer.sendToEvm(
|
const tx = await relayer.sendToEvm(
|
||||||
|
@ -350,11 +352,13 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
{ value, gasLimit: REASONABLE_GAS_LIMIT },
|
{ value, gasLimit: REASONABLE_GAS_LIMIT },
|
||||||
optionalParams
|
optionalParams
|
||||||
);
|
);
|
||||||
console.log("Sent delivery request!");
|
!ci && console.log("Sent delivery request!");
|
||||||
await tx.wait();
|
await tx.wait();
|
||||||
console.log("Message confirmed!");
|
!ci && console.log("Message confirmed!");
|
||||||
const endingBalance = await source.wallet.getBalance();
|
const endingBalance = await source.wallet.getBalance();
|
||||||
|
|
||||||
|
await source.provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
|
|
||||||
await waitForRelay();
|
await waitForRelay();
|
||||||
|
|
||||||
const info = (await relayer.getWormholeRelayerInfo(sourceChain, tx.hash, {
|
const info = (await relayer.getWormholeRelayerInfo(sourceChain, tx.hash, {
|
||||||
|
@ -362,30 +366,34 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
...optionalParams,
|
...optionalParams,
|
||||||
})) as relayer.DeliveryInfo;
|
})) as relayer.DeliveryInfo;
|
||||||
|
|
||||||
|
await target.provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
|
|
||||||
await waitForRelay();
|
await waitForRelay();
|
||||||
|
|
||||||
const newEndingBalance = await source.wallet.getBalance();
|
const newEndingBalance = await source.wallet.getBalance();
|
||||||
|
|
||||||
console.log(`Quoted gas delivery fee: ${value}`);
|
!ci && console.log(`Quoted gas delivery fee: ${value}`);
|
||||||
console.log(
|
!ci &&
|
||||||
`Cost (including gas) ${startingBalance.sub(endingBalance).toString()}`
|
console.log(
|
||||||
);
|
`Cost (including gas) ${startingBalance.sub(endingBalance).toString()}`
|
||||||
|
);
|
||||||
const refund = newEndingBalance.sub(endingBalance);
|
const refund = newEndingBalance.sub(endingBalance);
|
||||||
console.log(`Refund: ${refund.toString()}`);
|
!ci && console.log(`Refund: ${refund.toString()}`);
|
||||||
console.log(
|
!ci &&
|
||||||
`As a percentage of original value: ${newEndingBalance
|
console.log(
|
||||||
.sub(endingBalance)
|
`As a percentage of original value: ${newEndingBalance
|
||||||
.mul(100)
|
.sub(endingBalance)
|
||||||
.div(value)
|
.mul(100)
|
||||||
.toString()}%`
|
.div(value)
|
||||||
);
|
.toString()}%`
|
||||||
console.log("Confirming refund is nonzero");
|
);
|
||||||
|
!ci && console.log("Confirming refund is nonzero");
|
||||||
expect(refund.gt(0)).toBe(true);
|
expect(refund.gt(0)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Executes a Receiver Failure", async () => {
|
test("Executes a Receiver Failure", async () => {
|
||||||
const arbitraryPayload = getArbitraryBytes32();
|
const arbitraryPayload = getArbitraryBytes32();
|
||||||
console.log(`Sent message: ${arbitraryPayload}`);
|
!ci && console.log(`Sent message: ${arbitraryPayload}`);
|
||||||
|
|
||||||
const rx = await testSend(arbitraryPayload, false, true);
|
const rx = await testSend(arbitraryPayload, false, true);
|
||||||
|
|
||||||
|
@ -397,7 +405,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
|
|
||||||
test("Executes a receiver failure and then redelivery through SDK", async () => {
|
test("Executes a receiver failure and then redelivery through SDK", async () => {
|
||||||
const arbitraryPayload = getArbitraryBytes32();
|
const arbitraryPayload = getArbitraryBytes32();
|
||||||
console.log(`Sent message: ${arbitraryPayload}`);
|
!ci && console.log(`Sent message: ${arbitraryPayload}`);
|
||||||
|
|
||||||
const rx = await testSend(arbitraryPayload, false, true);
|
const rx = await testSend(arbitraryPayload, false, true);
|
||||||
|
|
||||||
|
@ -419,7 +427,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
{ wormholeRelayerAddresses, ...optionalParams }
|
{ wormholeRelayerAddresses, ...optionalParams }
|
||||||
)) as relayer.DeliveryInfo;
|
)) as relayer.DeliveryInfo;
|
||||||
|
|
||||||
console.log("Redelivering message");
|
!ci && console.log("Redelivering message");
|
||||||
const redeliveryReceipt = await relayer.resend(
|
const redeliveryReceipt = await relayer.resend(
|
||||||
source.wallet,
|
source.wallet,
|
||||||
sourceChain,
|
sourceChain,
|
||||||
|
@ -444,13 +452,13 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
{ wormholeRelayerAddress: source.wormholeRelayerAddress }
|
{ wormholeRelayerAddress: source.wormholeRelayerAddress }
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log("redelivery tx:", redeliveryReceipt.hash);
|
!ci && console.log("redelivery tx:", redeliveryReceipt.hash);
|
||||||
|
|
||||||
await redeliveryReceipt.wait();
|
await redeliveryReceipt.wait();
|
||||||
|
|
||||||
await waitForRelay();
|
await waitForRelay();
|
||||||
|
|
||||||
console.log("Checking if message was relayed after redelivery");
|
!ci && console.log("Checking if message was relayed after redelivery");
|
||||||
const message2 = await target.mockIntegration.getMessage();
|
const message2 = await target.mockIntegration.getMessage();
|
||||||
expect(message2).toBe(arbitraryPayload);
|
expect(message2).toBe(arbitraryPayload);
|
||||||
|
|
||||||
|
@ -464,9 +472,10 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
|
|
||||||
const currentAddress =
|
const currentAddress =
|
||||||
await source.wormholeRelayer.getRegisteredWormholeRelayerContract(chain);
|
await source.wormholeRelayer.getRegisteredWormholeRelayerContract(chain);
|
||||||
console.log(
|
!ci &&
|
||||||
`For Chain ${source.chainId}, registered chain ${chain} address: ${currentAddress}`
|
console.log(
|
||||||
);
|
`For Chain ${source.chainId}, registered chain ${chain} address: ${currentAddress}`
|
||||||
|
);
|
||||||
|
|
||||||
const expectedNewRegisteredAddress =
|
const expectedNewRegisteredAddress =
|
||||||
"0x0000000000000000000000001234567890123456789012345678901234567892";
|
"0x0000000000000000000000001234567890123456789012345678901234567892";
|
||||||
|
@ -501,9 +510,10 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
async () => {
|
async () => {
|
||||||
const currentAddress =
|
const currentAddress =
|
||||||
await source.wormholeRelayer.getDefaultDeliveryProvider();
|
await source.wormholeRelayer.getDefaultDeliveryProvider();
|
||||||
console.log(
|
!ci &&
|
||||||
`For Chain ${source.chainId}, default relay provider: ${currentAddress}`
|
console.log(
|
||||||
);
|
`For Chain ${source.chainId}, default relay provider: ${currentAddress}`
|
||||||
|
);
|
||||||
|
|
||||||
const expectedNewDefaultDeliveryProvider =
|
const expectedNewDefaultDeliveryProvider =
|
||||||
"0x1234567890123456789012345678901234567892";
|
"0x1234567890123456789012345678901234567892";
|
||||||
|
@ -567,9 +577,10 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
IMPLEMENTATION_STORAGE_SLOT
|
IMPLEMENTATION_STORAGE_SLOT
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(
|
!ci &&
|
||||||
`Current Implementation address: ${await getImplementationAddress()}`
|
console.log(
|
||||||
);
|
`Current Implementation address: ${await getImplementationAddress()}`
|
||||||
|
);
|
||||||
|
|
||||||
const wormholeAddress = CONTRACTS[network][sourceChain].core || "";
|
const wormholeAddress = CONTRACTS[network][sourceChain].core || "";
|
||||||
|
|
||||||
|
@ -579,10 +590,11 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
.then((x) => x.deployed())
|
.then((x) => x.deployed())
|
||||||
).address;
|
).address;
|
||||||
|
|
||||||
console.log(`Deployed!`);
|
!ci && console.log(`Deployed!`);
|
||||||
console.log(
|
!ci &&
|
||||||
`New core relayer implementation: ${newWormholeRelayerImplementationAddress}`
|
console.log(
|
||||||
);
|
`New core relayer implementation: ${newWormholeRelayerImplementationAddress}`
|
||||||
|
);
|
||||||
|
|
||||||
const timestamp = (await source.wallet.provider.getBlock("latest"))
|
const timestamp = (await source.wallet.provider.getBlock("latest"))
|
||||||
.timestamp;
|
.timestamp;
|
||||||
|
@ -598,6 +610,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
let tx = await source.wormholeRelayer.submitContractUpgrade(firstSignedVaa);
|
let tx = await source.wormholeRelayer.submitContractUpgrade(firstSignedVaa);
|
||||||
|
await tx.wait();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
ethers.utils.getAddress((await getImplementationAddress()).substring(26))
|
ethers.utils.getAddress((await getImplementationAddress()).substring(26))
|
||||||
|
@ -613,7 +626,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
const info = await relayer.getWormholeRelayerInfo(mySourceChain, txHash, {
|
const info = await relayer.getWormholeRelayerInfo(mySourceChain, txHash, {
|
||||||
environment,
|
environment,
|
||||||
});
|
});
|
||||||
console.log(info.stringified);
|
!ci && console.log(info.stringified);
|
||||||
});
|
});
|
||||||
|
|
||||||
testIfNotDevnet()("Tests custom manual delivery", async () => {
|
testIfNotDevnet()("Tests custom manual delivery", async () => {
|
||||||
|
@ -626,7 +639,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
const info = await relayer.getWormholeRelayerInfo(mySourceChain, txHash, {
|
const info = await relayer.getWormholeRelayerInfo(mySourceChain, txHash, {
|
||||||
environment,
|
environment,
|
||||||
});
|
});
|
||||||
console.log(info.stringified);
|
!ci && console.log(info.stringified);
|
||||||
|
|
||||||
const priceInfo = await manualDelivery(
|
const priceInfo = await manualDelivery(
|
||||||
mySourceChain,
|
mySourceChain,
|
||||||
|
@ -634,7 +647,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
{ environment },
|
{ environment },
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
console.log(`Price info: ${JSON.stringify(priceInfo)}`);
|
!ci && console.log(`Price info: ${JSON.stringify(priceInfo)}`);
|
||||||
|
|
||||||
const signer = new ethers.Wallet(
|
const signer = new ethers.Wallet(
|
||||||
PRIVATE_KEY,
|
PRIVATE_KEY,
|
||||||
|
@ -643,17 +656,19 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
: getDefaultProvider(environment, priceInfo.targetChain)
|
: getDefaultProvider(environment, priceInfo.targetChain)
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(
|
!ci &&
|
||||||
`Price: ${ethers.utils.formatEther(priceInfo.quote)} of ${
|
console.log(
|
||||||
priceInfo.targetChain
|
`Price: ${ethers.utils.formatEther(priceInfo.quote)} of ${
|
||||||
} currency`
|
priceInfo.targetChain
|
||||||
);
|
} currency`
|
||||||
|
);
|
||||||
const balance = await signer.getBalance();
|
const balance = await signer.getBalance();
|
||||||
console.log(
|
!ci &&
|
||||||
`My balance: ${ethers.utils.formatEther(balance)} of ${
|
console.log(
|
||||||
priceInfo.targetChain
|
`My balance: ${ethers.utils.formatEther(balance)} of ${
|
||||||
} currency`
|
priceInfo.targetChain
|
||||||
);
|
} currency`
|
||||||
|
);
|
||||||
|
|
||||||
const deliveryRx = await manualDelivery(
|
const deliveryRx = await manualDelivery(
|
||||||
mySourceChain,
|
mySourceChain,
|
||||||
|
@ -663,7 +678,7 @@ describe("Wormhole Relayer Tests", () => {
|
||||||
undefined,
|
undefined,
|
||||||
signer
|
signer
|
||||||
);
|
);
|
||||||
console.log("Manual delivery tx hash", deliveryRx.txHash);
|
!ci && console.log("Manual delivery tx hash", deliveryRx.txHash);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,20 +3,21 @@ import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"
|
||||||
import { describe, expect, jest, test } from "@jest/globals";
|
import { describe, expect, jest, test } from "@jest/globals";
|
||||||
import algosdk, {
|
import algosdk, {
|
||||||
Account,
|
Account,
|
||||||
|
OnApplicationComplete,
|
||||||
decodeAddress,
|
decodeAddress,
|
||||||
getApplicationAddress,
|
getApplicationAddress,
|
||||||
makeApplicationCallTxnFromObject,
|
makeApplicationCallTxnFromObject,
|
||||||
OnApplicationComplete,
|
|
||||||
waitForConfirmation,
|
waitForConfirmation,
|
||||||
} from "algosdk";
|
} from "algosdk";
|
||||||
import { BigNumber, ethers, utils } from "ethers";
|
import { BigNumber, ethers, utils } from "ethers";
|
||||||
import {
|
import {
|
||||||
approveEth,
|
|
||||||
attestFromAlgorand,
|
|
||||||
attestFromEth,
|
|
||||||
CHAIN_ID_ALGORAND,
|
CHAIN_ID_ALGORAND,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
|
WormholeWrappedInfo,
|
||||||
|
approveEth,
|
||||||
|
attestFromAlgorand,
|
||||||
|
attestFromEth,
|
||||||
createWrappedOnAlgorand,
|
createWrappedOnAlgorand,
|
||||||
createWrappedOnEth,
|
createWrappedOnEth,
|
||||||
getEmitterAddressAlgorand,
|
getEmitterAddressAlgorand,
|
||||||
|
@ -36,9 +37,7 @@ import {
|
||||||
transferFromEth,
|
transferFromEth,
|
||||||
uint8ArrayToHex,
|
uint8ArrayToHex,
|
||||||
updateWrappedOnEth,
|
updateWrappedOnEth,
|
||||||
WormholeWrappedInfo,
|
|
||||||
} from "../..";
|
} from "../..";
|
||||||
import { TokenImplementation__factory } from "../../ethers-contracts";
|
|
||||||
import { _parseVAAAlgorand } from "../../algorand";
|
import { _parseVAAAlgorand } from "../../algorand";
|
||||||
import {
|
import {
|
||||||
createAsset,
|
createAsset,
|
||||||
|
@ -49,6 +48,7 @@ import {
|
||||||
getTempAccounts,
|
getTempAccounts,
|
||||||
signSendAndConfirmAlgorand,
|
signSendAndConfirmAlgorand,
|
||||||
} from "../../algorand/__tests__/testHelpers";
|
} from "../../algorand/__tests__/testHelpers";
|
||||||
|
import { TokenImplementation__factory } from "../../ethers-contracts";
|
||||||
import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry";
|
import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry";
|
||||||
import { safeBigIntToNumber } from "../../utils/bigint";
|
import { safeBigIntToNumber } from "../../utils/bigint";
|
||||||
import {
|
import {
|
||||||
|
@ -61,8 +61,6 @@ import {
|
||||||
const CORE_ID = BigInt(1004);
|
const CORE_ID = BigInt(1004);
|
||||||
const TOKEN_BRIDGE_ID = BigInt(1006);
|
const TOKEN_BRIDGE_ID = BigInt(1006);
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
describe("Algorand tests", () => {
|
describe("Algorand tests", () => {
|
||||||
test("Algorand transfer native ALGO to Eth and back again", (done) => {
|
test("Algorand transfer native ALGO to Eth and back again", (done) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@ -115,7 +113,7 @@ describe("Algorand tests", () => {
|
||||||
{ transport: NodeHttpTransport() }
|
{ transport: NodeHttpTransport() }
|
||||||
);
|
);
|
||||||
const pvaa = _parseVAAAlgorand(vaaBytes);
|
const pvaa = _parseVAAAlgorand(vaaBytes);
|
||||||
const provider = new ethers.providers.WebSocketProvider(
|
const provider = new ethers.providers.JsonRpcProvider(
|
||||||
ETH_NODE_URL
|
ETH_NODE_URL
|
||||||
) as any;
|
) as any;
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
|
||||||
|
@ -262,6 +260,7 @@ describe("Algorand tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
|
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
|
@ -297,8 +296,6 @@ describe("Algorand tests", () => {
|
||||||
if (!secondFinalAlgoBal) {
|
if (!secondFinalAlgoBal) {
|
||||||
throw new Error("secondFinalAlgoBal is undefined");
|
throw new Error("secondFinalAlgoBal is undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.destroy();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Algorand ALGO transfer error:", e);
|
console.error("Algorand ALGO transfer error:", e);
|
||||||
done("Algorand ALGO transfer error");
|
done("Algorand ALGO transfer error");
|
||||||
|
@ -358,7 +355,7 @@ describe("Algorand tests", () => {
|
||||||
attestSn,
|
attestSn,
|
||||||
{ transport: NodeHttpTransport() }
|
{ transport: NodeHttpTransport() }
|
||||||
);
|
);
|
||||||
const provider = new ethers.providers.WebSocketProvider(
|
const provider = new ethers.providers.JsonRpcProvider(
|
||||||
ETH_NODE_URL
|
ETH_NODE_URL
|
||||||
) as any;
|
) as any;
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
|
||||||
|
@ -501,6 +498,7 @@ describe("Algorand tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
|
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
|
@ -537,7 +535,6 @@ describe("Algorand tests", () => {
|
||||||
throw new Error("secondFinalAlgoBal is undefined");
|
throw new Error("secondFinalAlgoBal is undefined");
|
||||||
}
|
}
|
||||||
expect(secondFinalAlgoBal - finalAlgoBal).toBe(parseInt(Amount) * 100);
|
expect(secondFinalAlgoBal - finalAlgoBal).toBe(parseInt(Amount) * 100);
|
||||||
provider.destroy();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Algorand chuckNorium transfer error:", e);
|
console.error("Algorand chuckNorium transfer error:", e);
|
||||||
done("Algorand chuckNorium transfer error");
|
done("Algorand chuckNorium transfer error");
|
||||||
|
@ -559,7 +556,7 @@ describe("Algorand tests", () => {
|
||||||
const algoWallet: Account = tempAccts[0];
|
const algoWallet: Account = tempAccts[0];
|
||||||
const Amount = "10";
|
const Amount = "10";
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
|
||||||
// attest the test token
|
// attest the test token
|
||||||
const attestReceipt = await attestFromEth(
|
const attestReceipt = await attestFromEth(
|
||||||
|
@ -575,6 +572,7 @@ describe("Algorand tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: attestSignedVaa } = await getSignedVAAWithRetry(
|
const { vaaBytes: attestSignedVaa } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -651,6 +649,7 @@ describe("Algorand tests", () => {
|
||||||
receipt,
|
receipt,
|
||||||
CONTRACTS.DEVNET.ethereum.core
|
CONTRACTS.DEVNET.ethereum.core
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: transferSignedVaa } = await getSignedVAAWithRetry(
|
const { vaaBytes: transferSignedVaa } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -776,7 +775,6 @@ describe("Algorand tests", () => {
|
||||||
);
|
);
|
||||||
expect(info.chainId).toBe(CHAIN_ID_ETH);
|
expect(info.chainId).toBe(CHAIN_ID_ETH);
|
||||||
expect(info.isWrapped).toBe(true);
|
expect(info.isWrapped).toBe(true);
|
||||||
provider.destroy();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Eth <=> Algorand error:", e);
|
console.error("Eth <=> Algorand error:", e);
|
||||||
done("Eth <=> Algorand error");
|
done("Eth <=> Algorand error");
|
||||||
|
@ -809,7 +807,7 @@ describe("Algorand tests", () => {
|
||||||
// ETH setup to transfer LUNA to Algorand
|
// ETH setup to transfer LUNA to Algorand
|
||||||
|
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
|
||||||
// attest the test token
|
// attest the test token
|
||||||
const receipt = await attestFromEth(
|
const receipt = await attestFromEth(
|
||||||
|
@ -825,6 +823,7 @@ describe("Algorand tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -880,6 +879,7 @@ describe("Algorand tests", () => {
|
||||||
const ethEmitterAddress = getEmitterAddressEth(
|
const ethEmitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: firstHalfVaa } = await getSignedVAAWithRetry(
|
const { vaaBytes: firstHalfVaa } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -925,6 +925,7 @@ describe("Algorand tests", () => {
|
||||||
secondHalfReceipt,
|
secondHalfReceipt,
|
||||||
CONTRACTS.DEVNET.ethereum.core
|
CONTRACTS.DEVNET.ethereum.core
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: secondHalfVaa } = await getSignedVAAWithRetry(
|
const { vaaBytes: secondHalfVaa } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -952,7 +953,6 @@ describe("Algorand tests", () => {
|
||||||
secondHalfVaa
|
secondHalfVaa
|
||||||
)
|
)
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
provider.destroy();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("new test error:", e);
|
console.error("new test error:", e);
|
||||||
done("new test error");
|
done("new test error");
|
||||||
|
|
|
@ -10,13 +10,13 @@ import {
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { parseUnits } from "ethers/lib/utils";
|
import { parseUnits } from "ethers/lib/utils";
|
||||||
import {
|
import {
|
||||||
approveEth,
|
|
||||||
APTOS_TOKEN_BRIDGE_EMITTER_ADDRESS,
|
APTOS_TOKEN_BRIDGE_EMITTER_ADDRESS,
|
||||||
attestFromAptos,
|
|
||||||
attestFromEth,
|
|
||||||
CHAIN_ID_APTOS,
|
CHAIN_ID_APTOS,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
|
approveEth,
|
||||||
|
attestFromAptos,
|
||||||
|
attestFromEth,
|
||||||
createWrappedOnAptos,
|
createWrappedOnAptos,
|
||||||
createWrappedOnEth,
|
createWrappedOnEth,
|
||||||
createWrappedTypeOnAptos,
|
createWrappedTypeOnAptos,
|
||||||
|
@ -56,8 +56,6 @@ import {
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
} from "./utils/consts";
|
} from "./utils/consts";
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
describe("Aptos SDK tests", () => {
|
describe("Aptos SDK tests", () => {
|
||||||
test("Transfer native token from Aptos to Ethereum", async () => {
|
test("Transfer native token from Aptos to Ethereum", async () => {
|
||||||
const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge;
|
const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge;
|
||||||
|
@ -99,7 +97,7 @@ describe("Aptos SDK tests", () => {
|
||||||
expect(attestVAA).toBeTruthy();
|
expect(attestVAA).toBeTruthy();
|
||||||
|
|
||||||
// setup ethereum
|
// setup ethereum
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const recipient = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
|
const recipient = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
|
||||||
const recipientAddress = await recipient.getAddress();
|
const recipientAddress = await recipient.getAddress();
|
||||||
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
|
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
|
||||||
|
@ -196,13 +194,10 @@ describe("Aptos SDK tests", () => {
|
||||||
expect(
|
expect(
|
||||||
balanceAfterTransferEth.sub(balanceBeforeTransferEth).toNumber()
|
balanceAfterTransferEth.sub(balanceBeforeTransferEth).toNumber()
|
||||||
).toEqual(10_000_000);
|
).toEqual(10_000_000);
|
||||||
|
|
||||||
// clean up
|
|
||||||
provider.destroy();
|
|
||||||
});
|
});
|
||||||
test("Transfer native ERC-20 from Ethereum to Aptos", async () => {
|
test("Transfer native ERC-20 from Ethereum to Aptos", async () => {
|
||||||
// setup ethereum
|
// setup ethereum
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const sender = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
|
const sender = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
|
||||||
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
|
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
|
||||||
const ethCoreBridge = CONTRACTS.DEVNET.ethereum.core;
|
const ethCoreBridge = CONTRACTS.DEVNET.ethereum.core;
|
||||||
|
@ -218,6 +213,7 @@ describe("Aptos SDK tests", () => {
|
||||||
let sequence = parseSequenceFromLogEth(attestReceipt, ethCoreBridge);
|
let sequence = parseSequenceFromLogEth(attestReceipt, ethCoreBridge);
|
||||||
expect(sequence).toBeTruthy();
|
expect(sequence).toBeTruthy();
|
||||||
|
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
const { vaaBytes: attestVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: attestVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
|
@ -322,6 +318,7 @@ describe("Aptos SDK tests", () => {
|
||||||
sequence = parseSequenceFromLogEth(transferReceipt, ethCoreBridge);
|
sequence = parseSequenceFromLogEth(transferReceipt, ethCoreBridge);
|
||||||
expect(sequence).toBeTruthy();
|
expect(sequence).toBeTruthy();
|
||||||
|
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
const { vaaBytes: transferVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: transferVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
|
@ -367,9 +364,6 @@ describe("Aptos SDK tests", () => {
|
||||||
expect(
|
expect(
|
||||||
balanceBeforeTransferEth.sub(balanceAfterTransferEth).toString()
|
balanceBeforeTransferEth.sub(balanceAfterTransferEth).toString()
|
||||||
).toEqual(amount.toString());
|
).toEqual(amount.toString());
|
||||||
|
|
||||||
// clean up
|
|
||||||
provider.destroy();
|
|
||||||
});
|
});
|
||||||
test("Transfer native token with payload from Aptos to Ethereum", async () => {
|
test("Transfer native token with payload from Aptos to Ethereum", async () => {
|
||||||
const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge;
|
const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge;
|
||||||
|
@ -411,7 +405,7 @@ describe("Aptos SDK tests", () => {
|
||||||
expect(attestVAA).toBeTruthy();
|
expect(attestVAA).toBeTruthy();
|
||||||
|
|
||||||
// setup ethereum
|
// setup ethereum
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const recipient = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
|
const recipient = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
|
||||||
const recipientAddress = await recipient.getAddress();
|
const recipientAddress = await recipient.getAddress();
|
||||||
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
|
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
|
||||||
|
@ -513,9 +507,6 @@ describe("Aptos SDK tests", () => {
|
||||||
expect(
|
expect(
|
||||||
balanceAfterTransferEth.sub(balanceBeforeTransferEth).toNumber()
|
balanceAfterTransferEth.sub(balanceBeforeTransferEth).toNumber()
|
||||||
).toEqual(10_000_000);
|
).toEqual(10_000_000);
|
||||||
|
|
||||||
// clean up
|
|
||||||
provider.destroy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,9 @@ import { formatUnits, parseUnits } from "@ethersproject/units";
|
||||||
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||||
import { describe, expect, jest, test } from "@jest/globals";
|
import { describe, expect, jest, test } from "@jest/globals";
|
||||||
import {
|
import {
|
||||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
TOKEN_PROGRAM_ID,
|
||||||
createAssociatedTokenAccountInstruction,
|
createAssociatedTokenAccountInstruction,
|
||||||
getAssociatedTokenAddress,
|
getAssociatedTokenAddress,
|
||||||
TOKEN_PROGRAM_ID,
|
|
||||||
} from "@solana/spl-token";
|
} from "@solana/spl-token";
|
||||||
import {
|
import {
|
||||||
Connection,
|
Connection,
|
||||||
|
@ -16,11 +15,11 @@ import {
|
||||||
} from "@solana/web3.js";
|
} from "@solana/web3.js";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import {
|
import {
|
||||||
approveEth,
|
|
||||||
attestFromEth,
|
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
|
approveEth,
|
||||||
|
attestFromEth,
|
||||||
createWrappedOnSolana,
|
createWrappedOnSolana,
|
||||||
getEmitterAddressEth,
|
getEmitterAddressEth,
|
||||||
getForeignAssetSolana,
|
getForeignAssetSolana,
|
||||||
|
@ -43,8 +42,6 @@ import {
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
} from "./utils/consts";
|
} from "./utils/consts";
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
async function transferFromEthToSolana(): Promise<string> {
|
async function transferFromEthToSolana(): Promise<string> {
|
||||||
// create a keypair for Solana
|
// create a keypair for Solana
|
||||||
const connection = new Connection(SOLANA_HOST, "confirmed");
|
const connection = new Connection(SOLANA_HOST, "confirmed");
|
||||||
|
@ -82,7 +79,7 @@ async function transferFromEthToSolana(): Promise<string> {
|
||||||
await connection.confirmTransaction(txid);
|
await connection.confirmTransaction(txid);
|
||||||
}
|
}
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
|
||||||
const amount = parseUnits("1", 18);
|
const amount = parseUnits("1", 18);
|
||||||
// approve the bridge to spend tokens
|
// approve the bridge to spend tokens
|
||||||
|
@ -106,7 +103,6 @@ async function transferFromEthToSolana(): Promise<string> {
|
||||||
receipt,
|
receipt,
|
||||||
CONTRACTS.DEVNET.ethereum.core
|
CONTRACTS.DEVNET.ethereum.core
|
||||||
);
|
);
|
||||||
provider.destroy();
|
|
||||||
return sequence;
|
return sequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +111,7 @@ describe("Ethereum to Solana and Back", () => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
|
||||||
// attest the test token
|
// attest the test token
|
||||||
const receipt = await attestFromEth(
|
const receipt = await attestFromEth(
|
||||||
|
@ -131,6 +127,7 @@ describe("Ethereum to Solana and Back", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -174,7 +171,6 @@ describe("Ethereum to Solana and Back", () => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// this could fail because the token is already attested (in an unclean env)
|
// this could fail because the token is already attested (in an unclean env)
|
||||||
}
|
}
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -238,7 +234,7 @@ describe("Ethereum to Solana and Back", () => {
|
||||||
await connection.confirmTransaction(txid);
|
await connection.confirmTransaction(txid);
|
||||||
}
|
}
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
|
||||||
const amount = parseUnits("1", DECIMALS);
|
const amount = parseUnits("1", DECIMALS);
|
||||||
|
|
||||||
|
@ -294,6 +290,7 @@ describe("Ethereum to Solana and Back", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -373,7 +370,6 @@ describe("Ethereum to Solana and Back", () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect(finalSolanaBalance - initialSolanaBalance === 1).toBe(true);
|
expect(finalSolanaBalance - initialSolanaBalance === 1).toBe(true);
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -393,6 +389,8 @@ describe("Ethereum to Solana and Back", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -466,6 +464,8 @@ describe("Ethereum to Solana and Back", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
import { beforeAll, afterAll, expect, jest, test } from "@jest/globals";
|
import { beforeAll, expect, jest, test } from "@jest/globals";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { parseUnits } from "ethers/lib/utils";
|
import { parseUnits } from "ethers/lib/utils";
|
||||||
|
import { Account, KeyPair, Near, connect, keyStores } from "near-api-js";
|
||||||
|
import {
|
||||||
|
FinalExecutionOutcome,
|
||||||
|
Provider,
|
||||||
|
getTransactionLastResult,
|
||||||
|
} from "near-api-js/lib/providers";
|
||||||
|
import { parseNearAmount } from "near-api-js/lib/utils/format";
|
||||||
import {
|
import {
|
||||||
createWrappedOnEth,
|
createWrappedOnEth,
|
||||||
createWrappedOnNear,
|
createWrappedOnNear,
|
||||||
|
@ -28,15 +35,6 @@ import {
|
||||||
TEST_ERC20,
|
TEST_ERC20,
|
||||||
} from "./utils/consts";
|
} from "./utils/consts";
|
||||||
import { getSignedVAABySequence } from "./utils/helpers";
|
import { getSignedVAABySequence } from "./utils/helpers";
|
||||||
import { Account, connect, KeyPair, keyStores, Near } from "near-api-js";
|
|
||||||
import {
|
|
||||||
FinalExecutionOutcome,
|
|
||||||
getTransactionLastResult,
|
|
||||||
Provider,
|
|
||||||
} from "near-api-js/lib/providers";
|
|
||||||
import { parseNearAmount } from "near-api-js/lib/utils/format";
|
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
let near: Near;
|
let near: Near;
|
||||||
let nearProvider: Provider;
|
let nearProvider: Provider;
|
||||||
|
@ -46,7 +44,7 @@ const accountId = "devnet.test.near";
|
||||||
const PRIVATE_KEY =
|
const PRIVATE_KEY =
|
||||||
"ed25519:nCW2EsTn91b7ettRqQX6ti8ZBNwo7tbMsenBu9nmSVG9aDhNB7hgw7S9w5M9CZu1bF23FbvhKZPfDmh2Gbs45Fs";
|
"ed25519:nCW2EsTn91b7ettRqQX6ti8ZBNwo7tbMsenBu9nmSVG9aDhNB7hgw7S9w5M9CZu1bF23FbvhKZPfDmh2Gbs45Fs";
|
||||||
|
|
||||||
const ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const ethProvider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY5, ethProvider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY5, ethProvider);
|
||||||
const ethEmitterAddress = getEmitterAddressEth(
|
const ethEmitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
|
@ -72,10 +70,6 @@ beforeAll(async () => {
|
||||||
ethWalletAddress = await signer.getAddress();
|
ethWalletAddress = await signer.getAddress();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
ethProvider.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
const nearParseLogAndGetSignedVaa = async (outcome: FinalExecutionOutcome) => {
|
const nearParseLogAndGetSignedVaa = async (outcome: FinalExecutionOutcome) => {
|
||||||
const sequence = parseSequenceFromLogNear(outcome);
|
const sequence = parseSequenceFromLogNear(outcome);
|
||||||
if (sequence === null) {
|
if (sequence === null) {
|
||||||
|
@ -155,6 +149,7 @@ test("Attest and transfer token from Ethereum to Near", async () => {
|
||||||
signer,
|
signer,
|
||||||
TEST_ERC20
|
TEST_ERC20
|
||||||
);
|
);
|
||||||
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt);
|
const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt);
|
||||||
const createWrappedMsgs = await createWrappedOnNear(
|
const createWrappedMsgs = await createWrappedOnNear(
|
||||||
nearProvider,
|
nearProvider,
|
||||||
|
@ -193,6 +188,7 @@ test("Attest and transfer token from Ethereum to Near", async () => {
|
||||||
"near",
|
"near",
|
||||||
hexToUint8Array(accountHash)
|
hexToUint8Array(accountHash)
|
||||||
);
|
);
|
||||||
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt);
|
const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt);
|
||||||
const redeemMsgs = await redeemOnNear(
|
const redeemMsgs = await redeemOnNear(
|
||||||
nearProvider,
|
nearProvider,
|
||||||
|
|
|
@ -2,10 +2,9 @@ import { formatUnits, parseUnits } from "@ethersproject/units";
|
||||||
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||||
import { describe, expect, jest, test } from "@jest/globals";
|
import { describe, expect, jest, test } from "@jest/globals";
|
||||||
import {
|
import {
|
||||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
||||||
getAssociatedTokenAddress,
|
|
||||||
NATIVE_MINT,
|
NATIVE_MINT,
|
||||||
TOKEN_PROGRAM_ID,
|
TOKEN_PROGRAM_ID,
|
||||||
|
getAssociatedTokenAddress,
|
||||||
} from "@solana/spl-token";
|
} from "@solana/spl-token";
|
||||||
import {
|
import {
|
||||||
Connection,
|
Connection,
|
||||||
|
@ -15,10 +14,11 @@ import {
|
||||||
} from "@solana/web3.js";
|
} from "@solana/web3.js";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import {
|
import {
|
||||||
attestFromSolana,
|
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
|
WSOL_ADDRESS,
|
||||||
|
attestFromSolana,
|
||||||
createWrappedOnEth,
|
createWrappedOnEth,
|
||||||
getEmitterAddressSolana,
|
getEmitterAddressSolana,
|
||||||
getForeignAssetEth,
|
getForeignAssetEth,
|
||||||
|
@ -30,7 +30,6 @@ import {
|
||||||
transferNativeSol,
|
transferNativeSol,
|
||||||
tryNativeToHexString,
|
tryNativeToHexString,
|
||||||
tryNativeToUint8Array,
|
tryNativeToUint8Array,
|
||||||
WSOL_ADDRESS,
|
|
||||||
} from "../..";
|
} from "../..";
|
||||||
import { TokenImplementation__factory } from "../../ethers-contracts";
|
import { TokenImplementation__factory } from "../../ethers-contracts";
|
||||||
import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry";
|
import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry";
|
||||||
|
@ -43,8 +42,6 @@ import {
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
} from "./utils/consts";
|
} from "./utils/consts";
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
describe("Solana to Ethereum", () => {
|
describe("Solana to Ethereum", () => {
|
||||||
test("Attest Solana SPL to Ethereum", (done) => {
|
test("Attest Solana SPL to Ethereum", (done) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@ -89,7 +86,7 @@ describe("Solana to Ethereum", () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
|
||||||
try {
|
try {
|
||||||
await createWrappedOnEth(
|
await createWrappedOnEth(
|
||||||
|
@ -100,7 +97,6 @@ describe("Solana to Ethereum", () => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// this could fail because the token is already attested (in an unclean env)
|
// this could fail because the token is already attested (in an unclean env)
|
||||||
}
|
}
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -111,7 +107,7 @@ describe("Solana to Ethereum", () => {
|
||||||
})();
|
})();
|
||||||
});
|
});
|
||||||
test("Solana SPL is attested on Ethereum", async () => {
|
test("Solana SPL is attested on Ethereum", async () => {
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const address = getForeignAssetEth(
|
const address = getForeignAssetEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge,
|
CONTRACTS.DEVNET.ethereum.token_bridge,
|
||||||
provider,
|
provider,
|
||||||
|
@ -120,13 +116,12 @@ describe("Solana to Ethereum", () => {
|
||||||
);
|
);
|
||||||
expect(address).toBeTruthy();
|
expect(address).toBeTruthy();
|
||||||
expect(address).not.toBe(ethers.constants.AddressZero);
|
expect(address).not.toBe(ethers.constants.AddressZero);
|
||||||
provider.destroy();
|
|
||||||
});
|
});
|
||||||
test("Send Solana SPL to Ethereum", (done) => {
|
test("Send Solana SPL to Ethereum", (done) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
|
||||||
const targetAddress = await signer.getAddress();
|
const targetAddress = await signer.getAddress();
|
||||||
// create a keypair for Solana
|
// create a keypair for Solana
|
||||||
|
@ -267,7 +262,6 @@ describe("Solana to Ethereum", () => {
|
||||||
parseInt(initialBalOnEthFormatted) ===
|
parseInt(initialBalOnEthFormatted) ===
|
||||||
1
|
1
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -318,7 +312,7 @@ describe("Solana to Ethereum", () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
|
||||||
try {
|
try {
|
||||||
await createWrappedOnEth(
|
await createWrappedOnEth(
|
||||||
|
@ -329,7 +323,6 @@ describe("Solana to Ethereum", () => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// this could fail because the token is already attested (in an unclean env)
|
// this could fail because the token is already attested (in an unclean env)
|
||||||
}
|
}
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -343,7 +336,7 @@ describe("Solana to Ethereum", () => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
|
||||||
const targetAddress = await signer.getAddress();
|
const targetAddress = await signer.getAddress();
|
||||||
// create a keypair for Solana
|
// create a keypair for Solana
|
||||||
|
@ -443,7 +436,6 @@ describe("Solana to Ethereum", () => {
|
||||||
parseInt(initialBalOnEthFormatted) ===
|
parseInt(initialBalOnEthFormatted) ===
|
||||||
1
|
1
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
|
||||||
import {
|
import { beforeAll, describe, expect, jest, test } from "@jest/globals";
|
||||||
afterAll,
|
|
||||||
beforeAll,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
jest,
|
|
||||||
test,
|
|
||||||
} from "@jest/globals";
|
|
||||||
import {
|
import {
|
||||||
Connection,
|
Connection,
|
||||||
Ed25519Keypair,
|
Ed25519Keypair,
|
||||||
|
@ -35,9 +28,7 @@ import {
|
||||||
getSignedVAAWithRetry,
|
getSignedVAAWithRetry,
|
||||||
parseAttestMetaVaa,
|
parseAttestMetaVaa,
|
||||||
parseSequenceFromLogEth,
|
parseSequenceFromLogEth,
|
||||||
parseTokenTransferPayload,
|
|
||||||
parseTokenTransferVaa,
|
parseTokenTransferVaa,
|
||||||
parseVaa,
|
|
||||||
redeemOnEth,
|
redeemOnEth,
|
||||||
redeemOnSui,
|
redeemOnSui,
|
||||||
transferFromEth,
|
transferFromEth,
|
||||||
|
@ -52,14 +43,12 @@ import {
|
||||||
getInnerType,
|
getInnerType,
|
||||||
getPackageId,
|
getPackageId,
|
||||||
getWrappedCoinType,
|
getWrappedCoinType,
|
||||||
newEmitterCap,
|
|
||||||
} from "../../sui";
|
} from "../../sui";
|
||||||
import {
|
import {
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SUI,
|
CHAIN_ID_SUI,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
hexToUint8Array,
|
hexToUint8Array,
|
||||||
parseTransferPayload,
|
|
||||||
tryNativeToHexString,
|
tryNativeToHexString,
|
||||||
tryNativeToUint8Array,
|
tryNativeToUint8Array,
|
||||||
} from "../../utils";
|
} from "../../utils";
|
||||||
|
@ -78,8 +67,6 @@ import {
|
||||||
mintAndTransferCoinSui,
|
mintAndTransferCoinSui,
|
||||||
} from "./utils/helpers";
|
} from "./utils/helpers";
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
// Sui constants
|
// Sui constants
|
||||||
const SUI_CORE_BRIDGE_STATE_OBJECT_ID = CONTRACTS.DEVNET.sui.core;
|
const SUI_CORE_BRIDGE_STATE_OBJECT_ID = CONTRACTS.DEVNET.sui.core;
|
||||||
const SUI_TOKEN_BRIDGE_STATE_OBJECT_ID = CONTRACTS.DEVNET.sui.token_bridge;
|
const SUI_TOKEN_BRIDGE_STATE_OBJECT_ID = CONTRACTS.DEVNET.sui.token_bridge;
|
||||||
|
@ -101,7 +88,7 @@ const suiSigner: RawSigner = new RawSigner(suiKeypair, suiProvider);
|
||||||
const ETH_CORE_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.core;
|
const ETH_CORE_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.core;
|
||||||
const ETH_TOKEN_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.token_bridge;
|
const ETH_TOKEN_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.token_bridge;
|
||||||
|
|
||||||
const ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const ethProvider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY10, ethProvider);
|
const ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY10, ethProvider);
|
||||||
|
|
||||||
let suiCoreBridgePackageId: string;
|
let suiCoreBridgePackageId: string;
|
||||||
|
@ -118,10 +105,6 @@ beforeAll(async () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
await ethProvider.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Modify the VAA to only have 1 guardian signature
|
// Modify the VAA to only have 1 guardian signature
|
||||||
// TODO: remove this when we can deploy the devnet core contract
|
// TODO: remove this when we can deploy the devnet core contract
|
||||||
// deterministically with multiple guardians in the initial guardian set
|
// deterministically with multiple guardians in the initial guardian set
|
||||||
|
@ -165,6 +148,7 @@ describe("Sui SDK tests", () => {
|
||||||
ETH_CORE_BRIDGE_ADDRESS
|
ETH_CORE_BRIDGE_ADDRESS
|
||||||
);
|
);
|
||||||
expect(attestSequence).toBeTruthy();
|
expect(attestSequence).toBeTruthy();
|
||||||
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
let { vaaBytes: attestVAA }: { vaaBytes: Uint8Array } =
|
let { vaaBytes: attestVAA }: { vaaBytes: Uint8Array } =
|
||||||
await getSignedVAAWithRetry(
|
await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -176,7 +160,6 @@ describe("Sui SDK tests", () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const slicedAttestVAA = sliceVAASignatures(attestVAA);
|
const slicedAttestVAA = sliceVAASignatures(attestVAA);
|
||||||
console.log(Buffer.from(slicedAttestVAA).toString("hex"));
|
|
||||||
expect(slicedAttestVAA).toBeTruthy();
|
expect(slicedAttestVAA).toBeTruthy();
|
||||||
|
|
||||||
// Start create wrapped on Sui
|
// Start create wrapped on Sui
|
||||||
|
@ -331,6 +314,7 @@ describe("Sui SDK tests", () => {
|
||||||
transferReceipt,
|
transferReceipt,
|
||||||
ETH_CORE_BRIDGE_ADDRESS
|
ETH_CORE_BRIDGE_ADDRESS
|
||||||
);
|
);
|
||||||
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
let { vaaBytes: transferFromEthVAA } = await getSignedVAAWithRetry(
|
let { vaaBytes: transferFromEthVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
|
@ -381,7 +365,6 @@ describe("Sui SDK tests", () => {
|
||||||
coinType: coinType,
|
coinType: coinType,
|
||||||
})
|
})
|
||||||
).data;
|
).data;
|
||||||
console.log({ coins, coinType });
|
|
||||||
const suiTransferTxPayload = await transferFromSui(
|
const suiTransferTxPayload = await transferFromSui(
|
||||||
suiProvider,
|
suiProvider,
|
||||||
SUI_CORE_BRIDGE_STATE_OBJECT_ID,
|
SUI_CORE_BRIDGE_STATE_OBJECT_ID,
|
||||||
|
@ -495,7 +478,6 @@ describe("Sui SDK tests", () => {
|
||||||
transport: NodeHttpTransport(),
|
transport: NodeHttpTransport(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
console.log(parseAttestMetaVaa(attestVAA));
|
|
||||||
expect(attestVAA).toBeTruthy();
|
expect(attestVAA).toBeTruthy();
|
||||||
|
|
||||||
// // Create wrapped on Ethereum
|
// // Create wrapped on Ethereum
|
||||||
|
|
|
@ -10,12 +10,12 @@ import {
|
||||||
} from "@terra-money/terra.js";
|
} from "@terra-money/terra.js";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import {
|
import {
|
||||||
approveEth,
|
|
||||||
attestFromEth,
|
|
||||||
attestFromTerra,
|
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_TERRA,
|
CHAIN_ID_TERRA,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
|
approveEth,
|
||||||
|
attestFromEth,
|
||||||
|
attestFromTerra,
|
||||||
createWrappedOnEth,
|
createWrappedOnEth,
|
||||||
createWrappedOnTerra,
|
createWrappedOnTerra,
|
||||||
getEmitterAddressEth,
|
getEmitterAddressEth,
|
||||||
|
@ -53,8 +53,6 @@ import {
|
||||||
waitForTerraExecution,
|
waitForTerraExecution,
|
||||||
} from "./utils/helpers";
|
} from "./utils/helpers";
|
||||||
|
|
||||||
jest.setTimeout(120000);
|
|
||||||
|
|
||||||
function sleep(ms: number) {
|
function sleep(ms: number) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
@ -106,7 +104,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
});
|
});
|
||||||
await broadcastAndWait(lcd, tx);
|
await broadcastAndWait(lcd, tx);
|
||||||
}
|
}
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
||||||
// attempt to transfer more than we've deposited
|
// attempt to transfer more than we've deposited
|
||||||
const transfer = new MsgExecuteContract(
|
const transfer = new MsgExecuteContract(
|
||||||
|
@ -186,7 +184,6 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
fee: feeEstimate,
|
fee: feeEstimate,
|
||||||
});
|
});
|
||||||
await broadcastAndWait(lcd, tx);
|
await broadcastAndWait(lcd, tx);
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -202,7 +199,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
||||||
// attest the test token
|
// attest the test token
|
||||||
const receipt = await attestFromEth(
|
const receipt = await attestFromEth(
|
||||||
|
@ -218,6 +215,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -265,7 +263,6 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// this could fail because the token is already attested (in an unclean env)
|
// this could fail because the token is already attested (in an unclean env)
|
||||||
}
|
}
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -293,7 +290,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(
|
const provider = new ethers.providers.JsonRpcProvider(
|
||||||
ETH_NODE_URL
|
ETH_NODE_URL
|
||||||
) as any;
|
) as any;
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
||||||
|
@ -381,6 +378,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -451,7 +449,6 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
tokenDefinition.decimals
|
tokenDefinition.decimals
|
||||||
);
|
);
|
||||||
// let finalCW20BalOnTerra: number = parseInt(balAmount);
|
// let finalCW20BalOnTerra: number = parseInt(balAmount);
|
||||||
provider.destroy();
|
|
||||||
done();
|
done();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -516,7 +513,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
sequence,
|
sequence,
|
||||||
emitterAddress
|
emitterAddress
|
||||||
);
|
);
|
||||||
const provider = new ethers.providers.WebSocketProvider(
|
const provider = new ethers.providers.JsonRpcProvider(
|
||||||
ETH_NODE_URL
|
ETH_NODE_URL
|
||||||
) as any;
|
) as any;
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
||||||
|
@ -538,7 +535,6 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
);
|
);
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
provider.destroy();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Attestation failure: ", e);
|
console.error("Attestation failure: ", e);
|
||||||
}
|
}
|
||||||
|
@ -567,7 +563,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
// const initialFeeBalance: number = await queryBalanceOnTerra(FeeAsset);
|
// const initialFeeBalance: number = await queryBalanceOnTerra(FeeAsset);
|
||||||
|
|
||||||
// Get initial balance of wrapped luna on Eth
|
// Get initial balance of wrapped luna on Eth
|
||||||
const provider = new ethers.providers.WebSocketProvider(
|
const provider = new ethers.providers.JsonRpcProvider(
|
||||||
ETH_NODE_URL
|
ETH_NODE_URL
|
||||||
) as any;
|
) as any;
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
||||||
|
@ -678,7 +674,6 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
expect(initialLunaBalOnEthInt + 1e6 === lunaBalOnEthAfterInt).toBe(
|
expect(initialLunaBalOnEthInt + 1e6 === lunaBalOnEthAfterInt).toBe(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
provider.destroy();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Terra to Ethereum failure: ", e);
|
console.error("Terra to Ethereum failure: ", e);
|
||||||
done("Terra to Ethereum Failure");
|
done("Terra to Ethereum Failure");
|
||||||
|
@ -701,7 +696,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
});
|
});
|
||||||
const Asset: string = "uluna";
|
const Asset: string = "uluna";
|
||||||
const initialTerraBalance: number = await queryBalanceOnTerra(Asset);
|
const initialTerraBalance: number = await queryBalanceOnTerra(Asset);
|
||||||
const provider = new ethers.providers.WebSocketProvider(
|
const provider = new ethers.providers.JsonRpcProvider(
|
||||||
ETH_NODE_URL
|
ETH_NODE_URL
|
||||||
) as any;
|
) as any;
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
||||||
|
@ -755,7 +750,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -813,7 +808,6 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
// const uusdBal = await queryBalanceOnTerra("uusd");
|
// const uusdBal = await queryBalanceOnTerra("uusd");
|
||||||
provider.destroy();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Transfer back failure: ", e);
|
console.error("Transfer back failure: ", e);
|
||||||
done("Transfer back Failure");
|
done("Transfer back Failure");
|
||||||
|
@ -890,7 +884,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
sequence,
|
sequence,
|
||||||
emitterAddress
|
emitterAddress
|
||||||
);
|
);
|
||||||
const provider = new ethers.providers.WebSocketProvider(
|
const provider = new ethers.providers.JsonRpcProvider(
|
||||||
ETH_NODE_URL
|
ETH_NODE_URL
|
||||||
) as any;
|
) as any;
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
|
||||||
|
@ -1070,7 +1064,7 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
emitterAddress = getEmitterAddressEth(
|
emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
|
@ -1132,7 +1126,6 @@ describe("Terra Classic Integration Tests", () => {
|
||||||
finalCW20BalOnTerra = parseInt(amount);
|
finalCW20BalOnTerra = parseInt(amount);
|
||||||
expect(finalCW20BalOnTerra - initialCW20BalOnTerra === 1).toBe(true);
|
expect(finalCW20BalOnTerra - initialCW20BalOnTerra === 1).toBe(true);
|
||||||
// Done checking wallet balances
|
// Done checking wallet balances
|
||||||
provider.destroy();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("CW20 Transfer failure: ", e);
|
console.error("CW20 Transfer failure: ", e);
|
||||||
done("CW20 Transfer Failure");
|
done("CW20 Transfer Failure");
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { beforeAll, afterAll, describe, expect, test } from "@jest/globals";
|
import { beforeAll, describe, expect, test } from "@jest/globals";
|
||||||
import {
|
import {
|
||||||
isTxError,
|
|
||||||
LCDClient,
|
LCDClient,
|
||||||
MnemonicKey,
|
MnemonicKey,
|
||||||
Msg,
|
Msg,
|
||||||
Wallet,
|
Wallet,
|
||||||
|
isTxError,
|
||||||
} from "@terra-money/terra.js";
|
} from "@terra-money/terra.js";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { parseUnits } from "ethers/lib/utils";
|
import { parseUnits } from "ethers/lib/utils";
|
||||||
|
@ -61,7 +61,7 @@ const terraClassicWallet = lcdClassic.wallet(
|
||||||
);
|
);
|
||||||
const terraClassicWalletAddress = terraClassicWallet.key.accAddress;
|
const terraClassicWalletAddress = terraClassicWallet.key.accAddress;
|
||||||
|
|
||||||
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
const signer = new ethers.Wallet(ETH_PRIVATE_KEY2, provider);
|
const signer = new ethers.Wallet(ETH_PRIVATE_KEY2, provider);
|
||||||
const ethEmitterAddress = getEmitterAddressEth(
|
const ethEmitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
|
@ -78,10 +78,6 @@ beforeAll(async () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
provider.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
const terraBroadcastAndWaitForExecution = async (
|
const terraBroadcastAndWaitForExecution = async (
|
||||||
msgs: Msg[],
|
msgs: Msg[],
|
||||||
wallet: Wallet,
|
wallet: Wallet,
|
||||||
|
@ -179,6 +175,7 @@ describe("Terra Integration Tests", () => {
|
||||||
signer,
|
signer,
|
||||||
TEST_ERC20
|
TEST_ERC20
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt);
|
const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt);
|
||||||
const createWrappedMsg = await createWrappedOnTerra(
|
const createWrappedMsg = await createWrappedOnTerra(
|
||||||
CONTRACTS.DEVNET.terra2.token_bridge,
|
CONTRACTS.DEVNET.terra2.token_bridge,
|
||||||
|
@ -201,6 +198,7 @@ describe("Terra Integration Tests", () => {
|
||||||
CHAIN_ID_TERRA2,
|
CHAIN_ID_TERRA2,
|
||||||
tryNativeToUint8Array(terraWalletAddress, CHAIN_ID_TERRA2)
|
tryNativeToUint8Array(terraWalletAddress, CHAIN_ID_TERRA2)
|
||||||
);
|
);
|
||||||
|
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt);
|
const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt);
|
||||||
const redeemMsg = await redeemOnTerra(
|
const redeemMsg = await redeemOnTerra(
|
||||||
CONTRACTS.DEVNET.terra2.token_bridge,
|
CONTRACTS.DEVNET.terra2.token_bridge,
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { describe, expect, it } from "@jest/globals";
|
|
||||||
import { Connection, PublicKey } from "@solana/web3.js";
|
|
||||||
|
|
||||||
const ci = !!process.env.CI;
|
const ci = !!process.env.CI;
|
||||||
|
|
||||||
// see devnet.md
|
// see devnet.md
|
||||||
export const ETH_NODE_URL = ci ? "ws://eth-devnet:8545" : "ws://localhost:8545";
|
export const ETH_NODE_URL = ci
|
||||||
|
? "http://eth-devnet:8545"
|
||||||
|
: "http://localhost:8545";
|
||||||
export const ETH_PRIVATE_KEY =
|
export const ETH_PRIVATE_KEY =
|
||||||
"0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"; // account 0
|
"0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"; // account 0
|
||||||
// account 1 used by NFT tests
|
// account 1 used by NFT tests
|
||||||
|
|
|
@ -52,8 +52,8 @@ const ci = !!process.env.CI;
|
||||||
const GUARDIAN_HOST = ci ? "guardian" : "localhost";
|
const GUARDIAN_HOST = ci ? "guardian" : "localhost";
|
||||||
const GUARDIAN_RPCS = [`http://${GUARDIAN_HOST}:7071`];
|
const GUARDIAN_RPCS = [`http://${GUARDIAN_HOST}:7071`];
|
||||||
const GUARDIAN_METRICS = `http://${GUARDIAN_HOST}:6060/metrics`;
|
const GUARDIAN_METRICS = `http://${GUARDIAN_HOST}:6060/metrics`;
|
||||||
const ETH_NODE_URL = ci ? "ws://eth-devnet:8545" : "ws://localhost:8545";
|
const ETH_NODE_URL = ci ? "http://eth-devnet:8545" : "http://localhost:8545";
|
||||||
const BSC_NODE_URL = ci ? "ws://eth-devnet2:8545" : "ws://localhost:8546";
|
const BSC_NODE_URL = ci ? "http://eth-devnet2:8545" : "http://localhost:8546";
|
||||||
const ETH_PRIVATE_KEY9 =
|
const ETH_PRIVATE_KEY9 =
|
||||||
"0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773";
|
"0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773";
|
||||||
const ETH_GA_TEST_TOKEN =
|
const ETH_GA_TEST_TOKEN =
|
||||||
|
@ -70,25 +70,23 @@ function sleep(ms) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ethProvider: ethers.providers.WebSocketProvider;
|
let ethProvider: ethers.providers.JsonRpcProvider;
|
||||||
let ethSigner: ethers.Wallet;
|
let ethSigner: ethers.Wallet;
|
||||||
let bscProvider: ethers.providers.WebSocketProvider;
|
let bscProvider: ethers.providers.JsonRpcProvider;
|
||||||
let bscSigner: ethers.Wallet;
|
let bscSigner: ethers.Wallet;
|
||||||
let cosmWasmClient: CosmWasmClient;
|
let cosmWasmClient: CosmWasmClient;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
// create a signer for Eth
|
// create a signer for Eth
|
||||||
ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL);
|
ethProvider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
|
||||||
ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY9, ethProvider);
|
ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY9, ethProvider);
|
||||||
// create a signer for BSC
|
// create a signer for BSC
|
||||||
bscProvider = new ethers.providers.WebSocketProvider(BSC_NODE_URL);
|
bscProvider = new ethers.providers.JsonRpcProvider(BSC_NODE_URL);
|
||||||
bscSigner = new ethers.Wallet(ETH_PRIVATE_KEY9, bscProvider);
|
bscSigner = new ethers.Wallet(ETH_PRIVATE_KEY9, bscProvider);
|
||||||
cosmWasmClient = await CosmWasmClient.connect(TENDERMINT_URL);
|
cosmWasmClient = await CosmWasmClient.connect(TENDERMINT_URL);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await ethProvider.destroy();
|
|
||||||
await bscProvider.destroy();
|
|
||||||
cosmWasmClient.disconnect();
|
cosmWasmClient.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -165,9 +163,8 @@ describe("Global Accountant Tests", () => {
|
||||||
tryNativeToUint8Array(ETH_GA_TEST_TOKEN, CHAIN_ID_ETH)
|
tryNativeToUint8Array(ETH_GA_TEST_TOKEN, CHAIN_ID_ETH)
|
||||||
);
|
);
|
||||||
if (attestedAddress && attestedAddress !== ethers.constants.AddressZero) {
|
if (attestedAddress && attestedAddress !== ethers.constants.AddressZero) {
|
||||||
console.log("already attested");
|
// already attested
|
||||||
} else {
|
} else {
|
||||||
console.log("attesting...");
|
|
||||||
// attest the test token
|
// attest the test token
|
||||||
const receipt = await attestFromEth(
|
const receipt = await attestFromEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge,
|
CONTRACTS.DEVNET.ethereum.token_bridge,
|
||||||
|
@ -182,7 +179,7 @@ describe("Global Accountant Tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
console.log(`fetching vaa ${sequence}...`);
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
GUARDIAN_RPCS,
|
GUARDIAN_RPCS,
|
||||||
|
@ -193,7 +190,6 @@ describe("Global Accountant Tests", () => {
|
||||||
transport: NodeHttpTransport(),
|
transport: NodeHttpTransport(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
console.log("creating...");
|
|
||||||
await createWrappedOnEth(
|
await createWrappedOnEth(
|
||||||
CONTRACTS.DEVNET.bsc.token_bridge,
|
CONTRACTS.DEVNET.bsc.token_bridge,
|
||||||
bscSigner,
|
bscSigner,
|
||||||
|
@ -225,7 +221,6 @@ describe("Global Accountant Tests", () => {
|
||||||
);
|
);
|
||||||
const amount = parseUnits("1", DECIMALS);
|
const amount = parseUnits("1", DECIMALS);
|
||||||
// approve the bridge to spend tokens
|
// approve the bridge to spend tokens
|
||||||
console.log("approving...");
|
|
||||||
await approveEth(
|
await approveEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge,
|
CONTRACTS.DEVNET.ethereum.token_bridge,
|
||||||
ETH_GA_TEST_TOKEN,
|
ETH_GA_TEST_TOKEN,
|
||||||
|
@ -233,7 +228,6 @@ describe("Global Accountant Tests", () => {
|
||||||
amount
|
amount
|
||||||
);
|
);
|
||||||
// transfer tokens out
|
// transfer tokens out
|
||||||
console.log("transferring...");
|
|
||||||
const receipt = await transferFromEth(
|
const receipt = await transferFromEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge,
|
CONTRACTS.DEVNET.ethereum.token_bridge,
|
||||||
ethSigner,
|
ethSigner,
|
||||||
|
@ -250,7 +244,7 @@ describe("Global Accountant Tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge
|
CONTRACTS.DEVNET.ethereum.token_bridge
|
||||||
);
|
);
|
||||||
console.log(`fetching vaa ${sequence}...`);
|
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
GUARDIAN_RPCS,
|
GUARDIAN_RPCS,
|
||||||
|
@ -261,18 +255,12 @@ describe("Global Accountant Tests", () => {
|
||||||
transport: NodeHttpTransport(),
|
transport: NodeHttpTransport(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
console.log("redeeming...");
|
|
||||||
await redeemOnEth(
|
await redeemOnEth(
|
||||||
CONTRACTS.DEVNET.bsc.token_bridge,
|
CONTRACTS.DEVNET.bsc.token_bridge,
|
||||||
bscSigner,
|
bscSigner,
|
||||||
signedVAA
|
signedVAA
|
||||||
);
|
);
|
||||||
const afterMetrics = await fetchGlobalAccountantMetrics();
|
const afterMetrics = await fetchGlobalAccountantMetrics();
|
||||||
console.log(
|
|
||||||
"approved b/a:",
|
|
||||||
beforeMetrics.global_accountant_transfer_vaas_submitted_and_approved,
|
|
||||||
afterMetrics.global_accountant_transfer_vaas_submitted_and_approved
|
|
||||||
);
|
|
||||||
if (
|
if (
|
||||||
afterMetrics.global_accountant_events_received <=
|
afterMetrics.global_accountant_events_received <=
|
||||||
beforeMetrics.global_accountant_events_received ||
|
beforeMetrics.global_accountant_events_received ||
|
||||||
|
@ -333,7 +321,6 @@ describe("Global Accountant Tests", () => {
|
||||||
);
|
);
|
||||||
const amount = parseUnits("1", DECIMALS);
|
const amount = parseUnits("1", DECIMALS);
|
||||||
// approve the bridge to spend tokens
|
// approve the bridge to spend tokens
|
||||||
console.log("approving...");
|
|
||||||
await approveEth(
|
await approveEth(
|
||||||
CONTRACTS.DEVNET.bsc.token_bridge,
|
CONTRACTS.DEVNET.bsc.token_bridge,
|
||||||
attestedAddress,
|
attestedAddress,
|
||||||
|
@ -341,7 +328,6 @@ describe("Global Accountant Tests", () => {
|
||||||
amount
|
amount
|
||||||
);
|
);
|
||||||
// transfer tokens out
|
// transfer tokens out
|
||||||
console.log("transferring...");
|
|
||||||
const receipt = await transferFromEth(
|
const receipt = await transferFromEth(
|
||||||
CONTRACTS.DEVNET.bsc.token_bridge,
|
CONTRACTS.DEVNET.bsc.token_bridge,
|
||||||
bscSigner,
|
bscSigner,
|
||||||
|
@ -358,7 +344,7 @@ describe("Global Accountant Tests", () => {
|
||||||
const emitterAddress = getEmitterAddressEth(
|
const emitterAddress = getEmitterAddressEth(
|
||||||
CONTRACTS.DEVNET.bsc.token_bridge
|
CONTRACTS.DEVNET.bsc.token_bridge
|
||||||
);
|
);
|
||||||
console.log(`fetching vaa ${sequence}...`);
|
await bscProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
// poll until the guardian(s) witness and sign the vaa
|
// poll until the guardian(s) witness and sign the vaa
|
||||||
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
|
||||||
GUARDIAN_RPCS,
|
GUARDIAN_RPCS,
|
||||||
|
@ -369,18 +355,12 @@ describe("Global Accountant Tests", () => {
|
||||||
transport: NodeHttpTransport(),
|
transport: NodeHttpTransport(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
console.log("redeeming...");
|
|
||||||
await redeemOnEth(
|
await redeemOnEth(
|
||||||
CONTRACTS.DEVNET.ethereum.token_bridge,
|
CONTRACTS.DEVNET.ethereum.token_bridge,
|
||||||
ethSigner,
|
ethSigner,
|
||||||
signedVAA
|
signedVAA
|
||||||
);
|
);
|
||||||
const afterMetrics = await fetchGlobalAccountantMetrics();
|
const afterMetrics = await fetchGlobalAccountantMetrics();
|
||||||
console.log(
|
|
||||||
"approved b/a:",
|
|
||||||
beforeMetrics.global_accountant_transfer_vaas_submitted_and_approved,
|
|
||||||
afterMetrics.global_accountant_transfer_vaas_submitted_and_approved
|
|
||||||
);
|
|
||||||
if (
|
if (
|
||||||
afterMetrics.global_accountant_events_received <=
|
afterMetrics.global_accountant_events_received <=
|
||||||
beforeMetrics.global_accountant_events_received ||
|
beforeMetrics.global_accountant_events_received ||
|
||||||
|
@ -428,7 +408,6 @@ describe("Global Accountant Tests", () => {
|
||||||
// STEP 3a - redeem spoofed tokens
|
// STEP 3a - redeem spoofed tokens
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
console.log("redeeming spoofed tokens");
|
|
||||||
let vaa: VAA<TokenBridgeTransfer> = {
|
let vaa: VAA<TokenBridgeTransfer> = {
|
||||||
version: 1,
|
version: 1,
|
||||||
guardianSetIndex: 0,
|
guardianSetIndex: 0,
|
||||||
|
@ -471,7 +450,6 @@ describe("Global Accountant Tests", () => {
|
||||||
const beforeMetrics = await fetchGlobalAccountantMetrics();
|
const beforeMetrics = await fetchGlobalAccountantMetrics();
|
||||||
const amount = parseUnits("9000", DECIMALS);
|
const amount = parseUnits("9000", DECIMALS);
|
||||||
// approve the bridge to spend tokens
|
// approve the bridge to spend tokens
|
||||||
console.log("approving...");
|
|
||||||
await approveEth(
|
await approveEth(
|
||||||
CONTRACTS.DEVNET.bsc.token_bridge,
|
CONTRACTS.DEVNET.bsc.token_bridge,
|
||||||
attestedAddress,
|
attestedAddress,
|
||||||
|
@ -479,7 +457,6 @@ describe("Global Accountant Tests", () => {
|
||||||
amount
|
amount
|
||||||
);
|
);
|
||||||
// transfer tokens out
|
// transfer tokens out
|
||||||
console.log("transferring...");
|
|
||||||
const receipt = await transferFromEth(
|
const receipt = await transferFromEth(
|
||||||
CONTRACTS.DEVNET.bsc.token_bridge,
|
CONTRACTS.DEVNET.bsc.token_bridge,
|
||||||
bscSigner,
|
bscSigner,
|
||||||
|
@ -492,14 +469,9 @@ describe("Global Accountant Tests", () => {
|
||||||
receipt,
|
receipt,
|
||||||
CONTRACTS.DEVNET.bsc.core
|
CONTRACTS.DEVNET.bsc.core
|
||||||
);
|
);
|
||||||
console.log("waiting 30s to fetch metrics...");
|
await bscProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
|
||||||
await sleep(30 * 1000); // give the guardian a few seconds to pick up the transfers and attempt to submit them
|
await sleep(30 * 1000); // give the guardian a few seconds to pick up the transfers and attempt to submit them
|
||||||
const afterMetrics = await fetchGlobalAccountantMetrics();
|
const afterMetrics = await fetchGlobalAccountantMetrics();
|
||||||
console.log(
|
|
||||||
"balance errors b/a:",
|
|
||||||
beforeMetrics.global_accountant_total_balance_errors,
|
|
||||||
afterMetrics.global_accountant_total_balance_errors
|
|
||||||
);
|
|
||||||
if (
|
if (
|
||||||
afterMetrics.global_accountant_error_events_received <=
|
afterMetrics.global_accountant_error_events_received <=
|
||||||
beforeMetrics.global_accountant_error_events_received ||
|
beforeMetrics.global_accountant_error_events_received ||
|
||||||
|
@ -529,6 +501,5 @@ describe("Global Accountant Tests", () => {
|
||||||
).rejects.toThrow();
|
).rejects.toThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("success!");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1506,7 +1506,7 @@ describe("NTT Global Accountant Tests", () => {
|
||||||
`0x${mockTransferPayload(8, 10, SPOKE_CHAIN_A)}`,
|
`0x${mockTransferPayload(8, 10, SPOKE_CHAIN_A)}`,
|
||||||
0,
|
0,
|
||||||
{ value },
|
{ value },
|
||||||
relayerOptionalParameters
|
{ ...relayerOptionalParameters, consistencyLevel: 200 }
|
||||||
);
|
);
|
||||||
const receipt = await tx.wait();
|
const receipt = await tx.wait();
|
||||||
// get the sequence from the logs (needed to fetch the vaa)
|
// get the sequence from the logs (needed to fetch the vaa)
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
process.env.CI = true;
|
||||||
|
|
||||||
|
const info = console.info;
|
||||||
|
console.info = function (x) {
|
||||||
|
if (x !== "secp256k1 unavailable, reverting to browser version") {
|
||||||
|
info(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const warn = console.warn;
|
||||||
|
console.warn = function (x) {
|
||||||
|
if (
|
||||||
|
x !==
|
||||||
|
"bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)"
|
||||||
|
) {
|
||||||
|
warn(x);
|
||||||
|
}
|
||||||
|
};
|
|
@ -5,8 +5,8 @@
|
||||||
"main": "deploy_wormchain.ts",
|
"main": "deploy_wormchain.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"deploy-wormchain": "ts-node deploy_wormchain.ts",
|
"deploy-wormchain": "ts-node deploy_wormchain.ts",
|
||||||
"test-accountant": "jest test_accountant.ts --verbose",
|
"test-accountant": "jest test_accountant.ts --verbose --setupFiles ./ci-config.js",
|
||||||
"test-ntt-accountant": "jest test_ntt_accountant.ts --verbose",
|
"test-ntt-accountant": "jest test_ntt_accountant.ts --verbose --setupFiles ./ci-config.js",
|
||||||
"test-wormchain": "ts-node test_wormchain.ts",
|
"test-wormchain": "ts-node test_wormchain.ts",
|
||||||
"deploy-and-test": "npm run deploy-wormchain && npm run test-wormchain"
|
"deploy-and-test": "npm run deploy-wormchain && npm run test-wormchain"
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,6 @@ export async function getWallet(
|
||||||
mnemonic: string,
|
mnemonic: string,
|
||||||
options?: DirectSecp256k1HdWalletOptions
|
options?: DirectSecp256k1HdWalletOptions
|
||||||
): Promise<DirectSecp256k1HdWallet> {
|
): Promise<DirectSecp256k1HdWallet> {
|
||||||
console.log("wallet");
|
|
||||||
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
|
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
|
||||||
prefix: ADDRESS_PREFIX,
|
prefix: ADDRESS_PREFIX,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue