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