clients/js: attempt sdkV2 migration
This commit is contained in:
parent
33b2fbe72a
commit
0a55a85291
|
@ -244,7 +244,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: "16"
|
node-version: "20"
|
||||||
- run: |
|
- run: |
|
||||||
cd clients/js && make test
|
cd clients/js && make test
|
||||||
make docs
|
make docs
|
||||||
|
|
|
@ -248,16 +248,7 @@ Positionals:
|
||||||
Options:
|
Options:
|
||||||
--help Show help [boolean]
|
--help Show help [boolean]
|
||||||
--version Show version number [boolean]
|
--version Show version number [boolean]
|
||||||
-c, --chain chain name
|
-c, --chain chain name [string]
|
||||||
[choices: "unset", "solana", "ethereum", "terra", "bsc", "polygon",
|
|
||||||
"avalanche", "oasis", "algorand", "aurora", "fantom", "karura", "acala",
|
|
||||||
"klaytn", "celo", "near", "moonbeam", "neon", "terra2", "injective",
|
|
||||||
"osmosis", "sui", "aptos", "arbitrum", "optimism", "gnosis", "pythnet",
|
|
||||||
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "blast",
|
|
||||||
"xlayer", "linea", "berachain", "seievm", "wormchain", "cosmoshub", "evmos",
|
|
||||||
"kujira", "neutron", "celestia", "stargaze", "seda", "dymension",
|
|
||||||
"provenance", "sepolia", "arbitrum_sepolia", "base_sepolia",
|
|
||||||
"optimism_sepolia", "holesky", "polygon_sepolia"]
|
|
||||||
-n, --network Network
|
-n, --network Network
|
||||||
[required] [choices: "mainnet", "testnet", "devnet"]
|
[required] [choices: "mainnet", "testnet", "devnet"]
|
||||||
-a, --contract-address Contract to submit VAA to (override config) [string]
|
-a, --contract-address Contract to submit VAA to (override config) [string]
|
||||||
|
@ -307,26 +298,8 @@ Options:
|
||||||
Options:
|
Options:
|
||||||
--help Show help [boolean]
|
--help Show help [boolean]
|
||||||
--version Show version number [boolean]
|
--version Show version number [boolean]
|
||||||
--src-chain source chain
|
--src-chain source chain [string] [required]
|
||||||
[required] [choices: "solana", "ethereum", "terra", "bsc", "polygon",
|
--dst-chain destination chain [string] [required]
|
||||||
"avalanche", "oasis", "algorand", "aurora", "fantom", "karura", "acala",
|
|
||||||
"klaytn", "celo", "near", "moonbeam", "neon", "terra2", "injective",
|
|
||||||
"osmosis", "sui", "aptos", "arbitrum", "optimism", "gnosis", "pythnet",
|
|
||||||
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "blast",
|
|
||||||
"xlayer", "linea", "berachain", "seievm", "wormchain", "cosmoshub", "evmos",
|
|
||||||
"kujira", "neutron", "celestia", "stargaze", "seda", "dymension",
|
|
||||||
"provenance", "sepolia", "arbitrum_sepolia", "base_sepolia",
|
|
||||||
"optimism_sepolia", "holesky", "polygon_sepolia"]
|
|
||||||
--dst-chain destination chain
|
|
||||||
[required] [choices: "solana", "ethereum", "terra", "bsc", "polygon",
|
|
||||||
"avalanche", "oasis", "algorand", "aurora", "fantom", "karura", "acala",
|
|
||||||
"klaytn", "celo", "near", "moonbeam", "neon", "terra2", "injective",
|
|
||||||
"osmosis", "sui", "aptos", "arbitrum", "optimism", "gnosis", "pythnet",
|
|
||||||
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "blast",
|
|
||||||
"xlayer", "linea", "berachain", "seievm", "wormchain", "cosmoshub", "evmos",
|
|
||||||
"kujira", "neutron", "celestia", "stargaze", "seda", "dymension",
|
|
||||||
"provenance", "sepolia", "arbitrum_sepolia", "base_sepolia",
|
|
||||||
"optimism_sepolia", "holesky", "polygon_sepolia"]
|
|
||||||
--dst-addr destination address [string] [required]
|
--dst-addr destination address [string] [required]
|
||||||
--token-addr token address [string] [default: native token]
|
--token-addr token address [string] [default: native token]
|
||||||
--amount token amount [string] [required]
|
--amount token amount [string] [required]
|
||||||
|
@ -353,16 +326,7 @@ Options:
|
||||||
```sh
|
```sh
|
||||||
Positionals:
|
Positionals:
|
||||||
network Network [choices: "mainnet", "testnet", "devnet"]
|
network Network [choices: "mainnet", "testnet", "devnet"]
|
||||||
chain Source chain
|
chain Source chain [string]
|
||||||
[choices: "unset", "solana", "ethereum", "terra", "bsc", "polygon",
|
|
||||||
"avalanche", "oasis", "algorand", "aurora", "fantom", "karura", "acala",
|
|
||||||
"klaytn", "celo", "near", "moonbeam", "neon", "terra2", "injective",
|
|
||||||
"osmosis", "sui", "aptos", "arbitrum", "optimism", "gnosis", "pythnet",
|
|
||||||
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "blast",
|
|
||||||
"xlayer", "linea", "berachain", "seievm", "wormchain", "cosmoshub", "evmos",
|
|
||||||
"kujira", "neutron", "celestia", "stargaze", "seda", "dymension",
|
|
||||||
"provenance", "sepolia", "arbitrum_sepolia", "base_sepolia",
|
|
||||||
"optimism_sepolia", "holesky", "polygon_sepolia"]
|
|
||||||
tx Source transaction hash [string]
|
tx Source transaction hash [string]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,11 +42,13 @@
|
||||||
"@solana/web3.js": "^1.22.0",
|
"@solana/web3.js": "^1.22.0",
|
||||||
"@terra-money/terra.js": "^3.1.9",
|
"@terra-money/terra.js": "^3.1.9",
|
||||||
"@types/config": "^3.3.0",
|
"@types/config": "^3.3.0",
|
||||||
|
"@wormhole-foundation/sdk": "^0.7.0-beta.5",
|
||||||
"@xpla/xpla.js": "^0.2.1",
|
"@xpla/xpla.js": "^0.2.1",
|
||||||
"algosdk": "^2.4.0",
|
"algosdk": "^2.4.0",
|
||||||
"aptos": "^1.3.16",
|
"aptos": "^1.3.16",
|
||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
"base-64": "^1.0.0",
|
"base-64": "^1.0.0",
|
||||||
|
"bech32": "^2.0.0",
|
||||||
"binary-parser": "^2.0.2",
|
"binary-parser": "^2.0.2",
|
||||||
"bn.js": "^5.2.0",
|
"bn.js": "^5.2.0",
|
||||||
"bs58": "^4.0.1",
|
"bs58": "^4.0.1",
|
||||||
|
@ -65,12 +67,13 @@
|
||||||
"@types/bn.js": "^5.1.0",
|
"@types/bn.js": "^5.1.0",
|
||||||
"@types/bs58": "^4.0.1",
|
"@types/bs58": "^4.0.1",
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
|
"@types/node": "^20.12.12",
|
||||||
"@types/node-fetch": "^2.6.3",
|
"@types/node-fetch": "^2.6.3",
|
||||||
"@types/yargs": "^17.0.24",
|
"@types/yargs": "^17.0.24",
|
||||||
"copy-dir": "^1.3.0",
|
"copy-dir": "^1.3.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"ts-jest": "^29.1.2",
|
"ts-jest": "^29.1.2",
|
||||||
"tsx": "^4.12.0",
|
"tsx": "^4.12.0",
|
||||||
"typescript": "^4.6"
|
"typescript": "^5.4.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,24 +2,26 @@ import {
|
||||||
_submitVAAAlgorand,
|
_submitVAAAlgorand,
|
||||||
signSendAndConfirmAlgorand,
|
signSendAndConfirmAlgorand,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/algorand";
|
} from "@certusone/wormhole-sdk/lib/esm/algorand";
|
||||||
import {
|
|
||||||
CONTRACTS,
|
|
||||||
ChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { Account, Algodv2, mnemonicToSecretKey } from "algosdk";
|
import { Account, Algodv2, mnemonicToSecretKey } from "algosdk";
|
||||||
import { NETWORKS } from "./consts";
|
import { NETWORKS } from "./consts";
|
||||||
import { Network } from "./utils";
|
|
||||||
import { Payload, impossible } from "./vaa";
|
import { Payload, impossible } from "./vaa";
|
||||||
import { transferFromAlgorand } from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
import { transferFromAlgorand } from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
||||||
import { tryNativeToHexString } from "@certusone/wormhole-sdk/lib/esm/utils";
|
import { tryNativeToHexString } from "./sdk/array";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
chainToChainId,
|
||||||
|
contracts,
|
||||||
|
Network,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
export async function execute_algorand(
|
export async function execute_algorand(
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
vaa: Uint8Array,
|
vaa: Uint8Array,
|
||||||
network: Network
|
network: Network
|
||||||
) {
|
) {
|
||||||
const chainName = "algorand";
|
const chain: Chain = "Algorand";
|
||||||
const { key, rpc } = NETWORKS[network][chainName];
|
const { key, rpc } = NETWORKS[network][chain];
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for Algorand`);
|
throw Error(`No ${network} key defined for Algorand`);
|
||||||
}
|
}
|
||||||
|
@ -28,19 +30,19 @@ export async function execute_algorand(
|
||||||
throw Error(`No ${network} rpc defined for Algorand`);
|
throw Error(`No ${network} rpc defined for Algorand`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const contracts = CONTRACTS[network][chainName];
|
const coreContract = contracts.coreBridge(network, chain);
|
||||||
console.log("contracts", contracts);
|
console.log("contracts", contracts);
|
||||||
|
|
||||||
let target_contract: string;
|
let target_contract: string;
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
if (!contracts.core) {
|
if (!coreContract) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Core bridge address not defined for Algorand ${network}`
|
`Core bridge address not defined for Algorand ${network}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.core;
|
target_contract = coreContract;
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "GuardianSetUpgrade":
|
case "GuardianSetUpgrade":
|
||||||
console.log("Submitting new guardian set");
|
console.log("Submitting new guardian set");
|
||||||
|
@ -57,14 +59,12 @@ export async function execute_algorand(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "NFTBridge": {
|
case "NFTBridge": {
|
||||||
if (!contracts.nft_bridge) {
|
const nftContract = contracts.nftBridge.get(network, chain);
|
||||||
// NOTE: this code can safely be removed once the algorand NFT bridge is
|
if (!nftContract) {
|
||||||
// released, but it's fine for it to stay, as the condition will just be
|
|
||||||
// skipped once 'contracts.nft_bridge' is defined
|
|
||||||
throw new Error("NFT bridge not supported yet for Algorand");
|
throw new Error("NFT bridge not supported yet for Algorand");
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.nft_bridge;
|
target_contract = nftContract;
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "ContractUpgrade":
|
case "ContractUpgrade":
|
||||||
console.log("Upgrading contract");
|
console.log("Upgrading contract");
|
||||||
|
@ -84,13 +84,14 @@ export async function execute_algorand(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
if (!contracts.token_bridge) {
|
const tbContract = contracts.tokenBridge(network, chain);
|
||||||
|
if (!tbContract) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Token bridge address not defined for Algorand ${network}`
|
`Token bridge address not defined for Algorand ${network}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.token_bridge;
|
target_contract = tbContract;
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "ContractUpgrade":
|
case "ContractUpgrade":
|
||||||
console.log("Upgrading contract");
|
console.log("Upgrading contract");
|
||||||
|
@ -121,7 +122,7 @@ export async function execute_algorand(
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = BigInt(parseInt(target_contract));
|
const target = BigInt(parseInt(target_contract));
|
||||||
const CORE_ID = BigInt(parseInt(contracts.core));
|
const CORE_ID = BigInt(parseInt(coreContract));
|
||||||
const algodClient = getClient(network, rpc);
|
const algodClient = getClient(network, rpc);
|
||||||
const algoWallet: Account = mnemonicToSecretKey(key);
|
const algoWallet: Account = mnemonicToSecretKey(key);
|
||||||
|
|
||||||
|
@ -140,27 +141,29 @@ export async function execute_algorand(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transferAlgorand(
|
export async function transferAlgorand(
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
network: Network,
|
network: Network,
|
||||||
rpc: string
|
rpc: string
|
||||||
) {
|
) {
|
||||||
const { key } = NETWORKS[network].algorand;
|
const { key } = NETWORKS[network].Algorand;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for Algorand`);
|
throw Error(`No ${network} key defined for Algorand`);
|
||||||
}
|
}
|
||||||
const contracts = CONTRACTS[network].algorand;
|
|
||||||
const client = getClient(network, rpc);
|
const client = getClient(network, rpc);
|
||||||
const wallet: Account = mnemonicToSecretKey(key);
|
const wallet: Account = mnemonicToSecretKey(key);
|
||||||
const CORE_ID = BigInt(parseInt(contracts.core));
|
const CORE_ID = BigInt(parseInt(contracts.coreBridge(network, "Algorand")));
|
||||||
const TOKEN_BRIDGE_ID = BigInt(parseInt(contracts.token_bridge));
|
const TOKEN_BRIDGE_ID = BigInt(
|
||||||
const recipient = tryNativeToHexString(dstAddress, dstChain);
|
parseInt(contracts.tokenBridge(network, "Algorand"))
|
||||||
|
);
|
||||||
|
const recipient = tryNativeToHexString(dstAddress, chainToChainId(dstChain));
|
||||||
if (!recipient) {
|
if (!recipient) {
|
||||||
throw new Error("Failed to convert recipient address");
|
throw new Error("Failed to convert recipient address");
|
||||||
}
|
}
|
||||||
const assetId = tokenAddress === "native" ? BigInt(0) : BigInt(tokenAddress);
|
const assetId = tokenAddress === "native" ? BigInt(0) : BigInt(tokenAddress);
|
||||||
|
|
||||||
const txs = await transferFromAlgorand(
|
const txs = await transferFromAlgorand(
|
||||||
client,
|
client,
|
||||||
TOKEN_BRIDGE_ID,
|
TOKEN_BRIDGE_ID,
|
||||||
|
@ -169,7 +172,7 @@ export async function transferAlgorand(
|
||||||
assetId,
|
assetId,
|
||||||
BigInt(amount),
|
BigInt(amount),
|
||||||
recipient,
|
recipient,
|
||||||
dstChain,
|
toChainId(dstChain),
|
||||||
BigInt(0)
|
BigInt(0)
|
||||||
);
|
);
|
||||||
const result = await signSendAndConfirmAlgorand(client, txs, wallet);
|
const result = await signSendAndConfirmAlgorand(client, txs, wallet);
|
||||||
|
@ -182,7 +185,7 @@ function getClient(network: Network, rpc: string) {
|
||||||
algodServer: rpc,
|
algodServer: rpc,
|
||||||
algodPort: "",
|
algodPort: "",
|
||||||
};
|
};
|
||||||
if (network === "DEVNET") {
|
if (network === "Devnet") {
|
||||||
ALGORAND_HOST.algodToken =
|
ALGORAND_HOST.algodToken =
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||||
ALGORAND_HOST.algodPort = "4001";
|
ALGORAND_HOST.algodPort = "4001";
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
import {
|
|
||||||
CONTRACTS,
|
|
||||||
ChainId,
|
|
||||||
ChainName,
|
|
||||||
assertChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { transferFromAptos } from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
import { transferFromAptos } from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
||||||
import { AptosAccount, AptosClient, BCS, TxnBuilderTypes, Types } from "aptos";
|
import { AptosAccount, AptosClient, BCS, TxnBuilderTypes, Types } from "aptos";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { sha3_256 } from "js-sha3";
|
import { sha3_256 } from "js-sha3";
|
||||||
import { NETWORKS } from "./consts";
|
import { NETWORKS } from "./consts";
|
||||||
import { Network } from "./utils";
|
|
||||||
import { Payload, impossible } from "./vaa";
|
import { Payload, impossible } from "./vaa";
|
||||||
import { CHAINS, ensureHexPrefix } from "@certusone/wormhole-sdk";
|
import { CHAINS, ensureHexPrefix } from "@certusone/wormhole-sdk";
|
||||||
import { TokenBridgeState } from "@certusone/wormhole-sdk/lib/esm/aptos/types";
|
import { TokenBridgeState } from "@certusone/wormhole-sdk/lib/esm/aptos/types";
|
||||||
|
import { generateSignAndSubmitEntryFunction } from "@certusone/wormhole-sdk/lib/esm/utils";
|
||||||
import {
|
import {
|
||||||
generateSignAndSubmitEntryFunction,
|
Chain,
|
||||||
tryNativeToUint8Array,
|
ChainId,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils";
|
Network,
|
||||||
|
assertChainId,
|
||||||
|
contracts,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { tryNativeToUint8Array } from "./sdk/array";
|
||||||
|
|
||||||
export async function execute_aptos(
|
export async function execute_aptos(
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
|
@ -25,7 +24,7 @@ export async function execute_aptos(
|
||||||
contract: string | undefined,
|
contract: string | undefined,
|
||||||
rpc: string | undefined
|
rpc: string | undefined
|
||||||
) {
|
) {
|
||||||
const chain = "aptos";
|
const chain: Chain = "Aptos";
|
||||||
|
|
||||||
// turn VAA bytes into BCS format. That is, add a length prefix
|
// turn VAA bytes into BCS format. That is, add a length prefix
|
||||||
const serializer = new BCS.Serializer();
|
const serializer = new BCS.Serializer();
|
||||||
|
@ -34,7 +33,7 @@ export async function execute_aptos(
|
||||||
|
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
contract = contract ?? CONTRACTS[network][chain]["core"];
|
contract = contract ?? contracts.coreBridge(network, chain);
|
||||||
if (contract === undefined) {
|
if (contract === undefined) {
|
||||||
throw Error("core bridge contract is undefined");
|
throw Error("core bridge contract is undefined");
|
||||||
}
|
}
|
||||||
|
@ -71,7 +70,7 @@ export async function execute_aptos(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "NFTBridge": {
|
case "NFTBridge": {
|
||||||
contract = contract ?? CONTRACTS[network][chain]["nft_bridge"];
|
contract = contract ?? contracts.nftBridge(network, chain);
|
||||||
if (contract === undefined) {
|
if (contract === undefined) {
|
||||||
throw Error("nft bridge contract is undefined");
|
throw Error("nft bridge contract is undefined");
|
||||||
}
|
}
|
||||||
|
@ -120,7 +119,7 @@ export async function execute_aptos(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
contract = contract ?? CONTRACTS[network][chain]["token_bridge"];
|
contract = contract ?? contracts.tokenBridge(network, chain);
|
||||||
if (contract === undefined) {
|
if (contract === undefined) {
|
||||||
throw Error("token bridge contract is undefined");
|
throw Error("token bridge contract is undefined");
|
||||||
}
|
}
|
||||||
|
@ -180,7 +179,7 @@ export async function execute_aptos(
|
||||||
// offline:
|
// offline:
|
||||||
const tokenAddress = payload.tokenAddress;
|
const tokenAddress = payload.tokenAddress;
|
||||||
const tokenChain = payload.tokenChain;
|
const tokenChain = payload.tokenChain;
|
||||||
assertChain(tokenChain);
|
assertChainId(tokenChain);
|
||||||
let wrappedContract = deriveWrappedAssetAddress(
|
let wrappedContract = deriveWrappedAssetAddress(
|
||||||
hex(contract),
|
hex(contract),
|
||||||
tokenChain,
|
tokenChain,
|
||||||
|
@ -208,7 +207,7 @@ export async function execute_aptos(
|
||||||
// TODO: only handles wrapped assets for now
|
// TODO: only handles wrapped assets for now
|
||||||
const tokenAddress = payload.tokenAddress;
|
const tokenAddress = payload.tokenAddress;
|
||||||
const tokenChain = payload.tokenChain;
|
const tokenChain = payload.tokenChain;
|
||||||
assertChain(tokenChain);
|
assertChainId(tokenChain);
|
||||||
let wrappedContract = deriveWrappedAssetAddress(
|
let wrappedContract = deriveWrappedAssetAddress(
|
||||||
hex(contract),
|
hex(contract),
|
||||||
tokenChain,
|
tokenChain,
|
||||||
|
@ -243,22 +242,22 @@ export async function execute_aptos(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transferAptos(
|
export async function transferAptos(
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
network: Network,
|
network: Network,
|
||||||
rpc: string
|
rpc: string
|
||||||
) {
|
) {
|
||||||
const { key } = NETWORKS[network].aptos;
|
const { key } = NETWORKS[network].Aptos;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw new Error("No key for aptos");
|
throw new Error("No key for aptos");
|
||||||
}
|
}
|
||||||
rpc = rpc ?? NETWORKS[network].aptos.rpc;
|
rpc = rpc ?? NETWORKS[network].Aptos.rpc;
|
||||||
if (!rpc) {
|
if (!rpc) {
|
||||||
throw new Error("No rpc for aptos");
|
throw new Error("No rpc for aptos");
|
||||||
}
|
}
|
||||||
const { token_bridge } = CONTRACTS[network].aptos;
|
const token_bridge = contracts.tokenBridge(network, "Aptos");
|
||||||
if (!token_bridge) {
|
if (!token_bridge) {
|
||||||
throw new Error("token bridge contract is undefined");
|
throw new Error("token bridge contract is undefined");
|
||||||
}
|
}
|
||||||
|
@ -268,8 +267,8 @@ export async function transferAptos(
|
||||||
token_bridge,
|
token_bridge,
|
||||||
tokenAddress === "native" ? "0x1::aptos_coin::AptosCoin" : tokenAddress,
|
tokenAddress === "native" ? "0x1::aptos_coin::AptosCoin" : tokenAddress,
|
||||||
amount,
|
amount,
|
||||||
dstChain,
|
toChainId(dstChain),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain)
|
tryNativeToUint8Array(dstAddress, toChainId(dstChain))
|
||||||
);
|
);
|
||||||
const tx = (await generateSignAndSubmitEntryFunction(
|
const tx = (await generateSignAndSubmitEntryFunction(
|
||||||
client,
|
client,
|
||||||
|
@ -321,14 +320,14 @@ export function deriveResourceAccount(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function callEntryFunc(
|
export async function callEntryFunc(
|
||||||
network: "MAINNET" | "TESTNET" | "DEVNET",
|
network: Network,
|
||||||
rpc: string | undefined,
|
rpc: string | undefined,
|
||||||
module: string,
|
module: string,
|
||||||
func: string,
|
func: string,
|
||||||
ty_args: BCS.Seq<TxnBuilderTypes.TypeTag>,
|
ty_args: BCS.Seq<TxnBuilderTypes.TypeTag>,
|
||||||
args: BCS.Seq<BCS.Bytes>
|
args: BCS.Seq<BCS.Bytes>
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
let key: string | undefined = NETWORKS[network]["aptos"].key;
|
let key: string | undefined = NETWORKS[network]["Aptos"].key;
|
||||||
if (key === undefined) {
|
if (key === undefined) {
|
||||||
throw new Error("No key for aptos");
|
throw new Error("No key for aptos");
|
||||||
}
|
}
|
||||||
|
@ -338,7 +337,7 @@ export async function callEntryFunc(
|
||||||
if (typeof rpc != "undefined") {
|
if (typeof rpc != "undefined") {
|
||||||
client = new AptosClient(rpc);
|
client = new AptosClient(rpc);
|
||||||
} else {
|
} else {
|
||||||
client = new AptosClient(NETWORKS[network]["aptos"].rpc);
|
client = new AptosClient(NETWORKS[network]["Aptos"].rpc);
|
||||||
}
|
}
|
||||||
const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([
|
const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([
|
||||||
client.getAccount(accountFrom.address()),
|
client.getAccount(accountFrom.address()),
|
||||||
|
@ -388,14 +387,13 @@ export async function queryRegistrationsAptos(
|
||||||
network: Network,
|
network: Network,
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge"
|
module: "Core" | "NFTBridge" | "TokenBridge"
|
||||||
): Promise<Object> {
|
): Promise<Object> {
|
||||||
const n = NETWORKS[network]["aptos"];
|
const n = NETWORKS[network]["Aptos"];
|
||||||
const client = new AptosClient(n.rpc);
|
const client = new AptosClient(n.rpc);
|
||||||
const contracts = CONTRACTS[network]["aptos"];
|
|
||||||
let stateObjectId: string | undefined;
|
let stateObjectId: string | undefined;
|
||||||
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
stateObjectId = contracts.token_bridge;
|
stateObjectId = contracts.tokenBridge(network, "Aptos");
|
||||||
if (stateObjectId === undefined) {
|
if (stateObjectId === undefined) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for Aptos`);
|
throw Error(`Unknown token bridge contract on ${network} for Aptos`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,25 +10,38 @@ import {
|
||||||
getOriginalAssetXpla,
|
getOriginalAssetXpla,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/getOriginalAsset";
|
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/getOriginalAsset";
|
||||||
import { getOriginalAssetInjective } from "@certusone/wormhole-sdk/lib/esm/token_bridge/injective";
|
import { getOriginalAssetInjective } from "@certusone/wormhole-sdk/lib/esm/token_bridge/injective";
|
||||||
import {
|
|
||||||
ChainId,
|
|
||||||
ChainName,
|
|
||||||
coalesceChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { CONTRACTS } from "../../consts";
|
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { impossible } from "../../vaa";
|
import { impossible } from "../../vaa";
|
||||||
import { getOriginalAssetSei } from "../sei/sdk";
|
import { getOriginalAssetSei } from "../sei/sdk";
|
||||||
import { getProviderForChain } from "./provider";
|
import { getProviderForChain } from "./provider";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
ChainId,
|
||||||
|
Network,
|
||||||
|
chainToPlatform,
|
||||||
|
contracts,
|
||||||
|
toChain,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import {
|
||||||
|
TokenId,
|
||||||
|
Wormhole,
|
||||||
|
toChainId,
|
||||||
|
wormhole,
|
||||||
|
} from "@wormhole-foundation/sdk";
|
||||||
|
import evm from "@wormhole-foundation/sdk/evm";
|
||||||
|
import solana from "@wormhole-foundation/sdk/solana";
|
||||||
|
import algorand from "@wormhole-foundation/sdk/algorand";
|
||||||
|
import aptos from "@wormhole-foundation/sdk/aptos";
|
||||||
|
import cosmwasm from "@wormhole-foundation/sdk/cosmwasm";
|
||||||
|
import sui from "@wormhole-foundation/sdk/sui";
|
||||||
|
|
||||||
export const getOriginalAsset = async (
|
export const getOriginalAsset = async (
|
||||||
chain: ChainId | ChainName,
|
chain: ChainId | Chain,
|
||||||
network: Network,
|
network: Network,
|
||||||
assetAddress: string,
|
assetAddress: string,
|
||||||
rpc?: string
|
rpc?: string
|
||||||
): Promise<WormholeWrappedInfo> => {
|
): Promise<WormholeWrappedInfo> => {
|
||||||
const chainName = coalesceChainName(chain);
|
const chainName = toChain(chain);
|
||||||
const tokenBridgeAddress = CONTRACTS[network][chainName].token_bridge;
|
const tokenBridgeAddress = contracts.tokenBridge.get(network, chainName);
|
||||||
if (!tokenBridgeAddress) {
|
if (!tokenBridgeAddress) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Token bridge address not defined for ${chainName} ${network}`
|
`Token bridge address not defined for ${chainName} ${network}`
|
||||||
|
@ -36,69 +49,66 @@ export const getOriginalAsset = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (chainName) {
|
switch (chainName) {
|
||||||
case "unset":
|
case "Solana": {
|
||||||
throw new Error("Chain not set");
|
|
||||||
case "solana": {
|
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetSolana(provider, tokenBridgeAddress, assetAddress);
|
return getOriginalAssetSolana(provider, tokenBridgeAddress, assetAddress);
|
||||||
}
|
}
|
||||||
case "acala":
|
case "Acala":
|
||||||
case "arbitrum":
|
case "Arbitrum":
|
||||||
case "aurora":
|
case "Aurora":
|
||||||
case "avalanche":
|
case "Avalanche":
|
||||||
case "base":
|
case "Base":
|
||||||
case "bsc":
|
case "Bsc":
|
||||||
case "celo":
|
case "Celo":
|
||||||
case "ethereum":
|
case "Ethereum":
|
||||||
case "fantom":
|
case "Fantom":
|
||||||
case "gnosis":
|
case "Gnosis":
|
||||||
case "karura":
|
case "Karura":
|
||||||
case "klaytn":
|
case "Klaytn":
|
||||||
case "moonbeam":
|
case "Moonbeam":
|
||||||
case "neon":
|
case "Neon":
|
||||||
case "oasis":
|
case "Oasis":
|
||||||
case "optimism":
|
case "Optimism":
|
||||||
case "polygon":
|
case "Polygon":
|
||||||
// case "rootstock":
|
case "Scroll":
|
||||||
case "scroll":
|
case "Mantle":
|
||||||
case "mantle":
|
case "Blast":
|
||||||
case "blast":
|
case "Xlayer":
|
||||||
case "xlayer":
|
case "Linea":
|
||||||
case "linea":
|
case "Berachain":
|
||||||
case "berachain":
|
case "Seievm":
|
||||||
case "seievm":
|
case "Sepolia":
|
||||||
case "sepolia":
|
case "ArbitrumSepolia":
|
||||||
case "arbitrum_sepolia":
|
case "BaseSepolia":
|
||||||
case "base_sepolia":
|
case "OptimismSepolia":
|
||||||
case "optimism_sepolia":
|
case "PolygonSepolia":
|
||||||
case "polygon_sepolia":
|
case "Holesky": {
|
||||||
case "holesky": {
|
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetEth(
|
return getOriginalAssetEth(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
provider,
|
provider,
|
||||||
assetAddress,
|
assetAddress,
|
||||||
chain
|
toChainId(chain)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "terra":
|
case "Terra":
|
||||||
case "terra2": {
|
case "Terra2": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetTerra(provider, assetAddress);
|
return getOriginalAssetTerra(provider, assetAddress);
|
||||||
}
|
}
|
||||||
case "injective": {
|
case "Injective": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetInjective(assetAddress, provider);
|
return getOriginalAssetInjective(assetAddress, provider);
|
||||||
}
|
}
|
||||||
case "sei": {
|
case "Sei": {
|
||||||
const provider = await getProviderForChain(chainName, network, { rpc });
|
const provider = await getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetSei(assetAddress, provider);
|
return getOriginalAssetSei(assetAddress, provider);
|
||||||
}
|
}
|
||||||
case "xpla": {
|
case "Xpla": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetXpla(provider, assetAddress);
|
return getOriginalAssetXpla(provider, assetAddress);
|
||||||
}
|
}
|
||||||
case "algorand": {
|
case "Algorand": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetAlgorand(
|
return getOriginalAssetAlgorand(
|
||||||
provider,
|
provider,
|
||||||
|
@ -106,32 +116,32 @@ export const getOriginalAsset = async (
|
||||||
BigInt(assetAddress)
|
BigInt(assetAddress)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "near": {
|
case "Near": {
|
||||||
const provider = await getProviderForChain(chainName, network, { rpc });
|
const provider = await getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetNear(provider, tokenBridgeAddress, assetAddress);
|
return getOriginalAssetNear(provider, tokenBridgeAddress, assetAddress);
|
||||||
}
|
}
|
||||||
case "aptos": {
|
case "Aptos": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetAptos(provider, tokenBridgeAddress, assetAddress);
|
return getOriginalAssetAptos(provider, tokenBridgeAddress, assetAddress);
|
||||||
}
|
}
|
||||||
case "sui": {
|
case "Sui": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getOriginalAssetSui(provider, tokenBridgeAddress, assetAddress);
|
return getOriginalAssetSui(provider, tokenBridgeAddress, assetAddress);
|
||||||
}
|
}
|
||||||
case "btc":
|
case "Btc":
|
||||||
case "osmosis":
|
case "Osmosis":
|
||||||
case "pythnet":
|
case "Pythnet":
|
||||||
case "wormchain":
|
case "Wormchain":
|
||||||
case "cosmoshub":
|
case "Cosmoshub":
|
||||||
case "evmos":
|
case "Evmos":
|
||||||
case "kujira":
|
case "Kujira":
|
||||||
case "neutron":
|
case "Neutron":
|
||||||
case "celestia":
|
case "Celestia":
|
||||||
case "stargaze":
|
case "Stargaze":
|
||||||
case "seda":
|
case "Seda":
|
||||||
case "dymension":
|
case "Dymension":
|
||||||
case "provenance":
|
case "Provenance":
|
||||||
case "rootstock":
|
case "Rootstock":
|
||||||
throw new Error(`${chainName} not supported`);
|
throw new Error(`${chainName} not supported`);
|
||||||
default:
|
default:
|
||||||
impossible(chainName);
|
impossible(chainName);
|
||||||
|
|
|
@ -9,31 +9,32 @@ import {
|
||||||
getForeignAssetXpla,
|
getForeignAssetXpla,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/getForeignAsset";
|
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/getForeignAsset";
|
||||||
import { getForeignAssetInjective } from "@certusone/wormhole-sdk/lib/esm/token_bridge/injective";
|
import { getForeignAssetInjective } from "@certusone/wormhole-sdk/lib/esm/token_bridge/injective";
|
||||||
import { tryNativeToUint8Array } from "@certusone/wormhole-sdk/lib/esm/utils/array";
|
|
||||||
import {
|
|
||||||
ChainId,
|
|
||||||
ChainName,
|
|
||||||
coalesceChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { CONTRACTS } from "../../consts";
|
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { impossible } from "../../vaa";
|
import { impossible } from "../../vaa";
|
||||||
import { getForeignAssetSei } from "../sei/sdk";
|
import { getForeignAssetSei } from "../sei/sdk";
|
||||||
import { getProviderForChain } from "./provider";
|
import { getProviderForChain } from "./provider";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
ChainId,
|
||||||
|
Network,
|
||||||
|
contracts,
|
||||||
|
toChain,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { tryNativeToUint8Array } from "../../sdk/array";
|
||||||
|
|
||||||
export const getWrappedAssetAddress = async (
|
export const getWrappedAssetAddress = async (
|
||||||
chain: ChainId | ChainName,
|
chain: ChainId | Chain,
|
||||||
network: Network,
|
network: Network,
|
||||||
originChain: ChainId | ChainName,
|
originChain: ChainId | Chain,
|
||||||
originAddress: string,
|
originAddress: string,
|
||||||
rpc?: string
|
rpc?: string
|
||||||
): Promise<string | null> => {
|
): Promise<string | null> => {
|
||||||
const chainName = coalesceChainName(chain);
|
const chainName = toChain(chain);
|
||||||
const originAddressUint8Array = tryNativeToUint8Array(
|
const originAddressUint8Array = tryNativeToUint8Array(
|
||||||
originAddress,
|
originAddress,
|
||||||
originChain
|
originChain
|
||||||
);
|
);
|
||||||
const tokenBridgeAddress = CONTRACTS[network][chainName].token_bridge;
|
const tokenBridgeAddress = contracts.tokenBridge.get(network, chainName);
|
||||||
if (!tokenBridgeAddress) {
|
if (!tokenBridgeAddress) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Token bridge address not defined for ${chainName} ${network}`
|
`Token bridge address not defined for ${chainName} ${network}`
|
||||||
|
@ -41,143 +42,141 @@ export const getWrappedAssetAddress = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (chainName) {
|
switch (chainName) {
|
||||||
case "unset":
|
case "Solana": {
|
||||||
throw new Error("Chain not set");
|
|
||||||
case "solana": {
|
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetSolana(
|
return getForeignAssetSolana(
|
||||||
provider,
|
provider,
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddressUint8Array
|
originAddressUint8Array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "acala":
|
case "Acala":
|
||||||
case "arbitrum":
|
case "Arbitrum":
|
||||||
case "aurora":
|
case "Aurora":
|
||||||
case "avalanche":
|
case "Avalanche":
|
||||||
case "base":
|
case "Base":
|
||||||
case "bsc":
|
case "Bsc":
|
||||||
case "celo":
|
case "Celo":
|
||||||
case "ethereum":
|
case "Ethereum":
|
||||||
case "fantom":
|
case "Fantom":
|
||||||
case "gnosis":
|
case "Gnosis":
|
||||||
case "karura":
|
case "Karura":
|
||||||
case "klaytn":
|
case "Klaytn":
|
||||||
case "moonbeam":
|
case "Moonbeam":
|
||||||
case "neon":
|
case "Neon":
|
||||||
case "oasis":
|
case "Oasis":
|
||||||
case "optimism":
|
case "Optimism":
|
||||||
case "polygon":
|
case "Polygon":
|
||||||
// case "rootstock":
|
// case "Rootstock":
|
||||||
case "scroll":
|
case "Scroll":
|
||||||
case "mantle":
|
case "Mantle":
|
||||||
case "blast":
|
case "Blast":
|
||||||
case "xlayer":
|
case "Xlayer":
|
||||||
case "linea":
|
case "Linea":
|
||||||
case "berachain":
|
case "Berachain":
|
||||||
case "seievm":
|
case "Seievm":
|
||||||
case "sepolia":
|
case "Sepolia":
|
||||||
case "arbitrum_sepolia":
|
case "ArbitrumSepolia":
|
||||||
case "base_sepolia":
|
case "BaseSepolia":
|
||||||
case "optimism_sepolia":
|
case "OptimismSepolia":
|
||||||
case "polygon_sepolia":
|
case "PolygonSepolia":
|
||||||
case "holesky": {
|
case "Holesky": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetEth(
|
return getForeignAssetEth(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
provider,
|
provider,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddressUint8Array
|
originAddressUint8Array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "terra":
|
case "Terra":
|
||||||
case "terra2": {
|
case "Terra2": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetTerra(
|
return getForeignAssetTerra(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
provider,
|
provider,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddressUint8Array
|
originAddressUint8Array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "injective": {
|
case "Injective": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetInjective(
|
return getForeignAssetInjective(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
provider,
|
provider,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddressUint8Array
|
originAddressUint8Array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "sei": {
|
case "Sei": {
|
||||||
const provider = await getProviderForChain(chainName, network, { rpc });
|
const provider = await getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetSei(
|
return getForeignAssetSei(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
provider,
|
provider,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddressUint8Array
|
originAddressUint8Array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "xpla": {
|
case "Xpla": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetXpla(
|
return getForeignAssetXpla(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
provider,
|
provider,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddressUint8Array
|
originAddressUint8Array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "algorand": {
|
case "Algorand": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetAlgorand(
|
return getForeignAssetAlgorand(
|
||||||
provider,
|
provider,
|
||||||
BigInt(tokenBridgeAddress),
|
BigInt(tokenBridgeAddress),
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddress
|
originAddress
|
||||||
).then((x) => x?.toString() ?? null);
|
).then((x) => x?.toString() ?? null);
|
||||||
}
|
}
|
||||||
case "near": {
|
case "Near": {
|
||||||
const provider = await getProviderForChain(chainName, network, { rpc });
|
const provider = await getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetNear(
|
return getForeignAssetNear(
|
||||||
provider,
|
provider,
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddress
|
originAddress
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "aptos": {
|
case "Aptos": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetAptos(
|
return getForeignAssetAptos(
|
||||||
provider,
|
provider,
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddress
|
originAddress
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "sui": {
|
case "Sui": {
|
||||||
const provider = getProviderForChain(chainName, network, { rpc });
|
const provider = getProviderForChain(chainName, network, { rpc });
|
||||||
return getForeignAssetSui(
|
return getForeignAssetSui(
|
||||||
provider,
|
provider,
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
originChain,
|
toChainId(originChain),
|
||||||
originAddressUint8Array
|
originAddressUint8Array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "btc":
|
case "Btc":
|
||||||
case "osmosis":
|
case "Osmosis":
|
||||||
case "pythnet":
|
case "Pythnet":
|
||||||
case "wormchain":
|
case "Wormchain":
|
||||||
case "cosmoshub":
|
case "Cosmoshub":
|
||||||
case "evmos":
|
case "Evmos":
|
||||||
case "kujira":
|
case "Kujira":
|
||||||
case "neutron":
|
case "Neutron":
|
||||||
case "celestia":
|
case "Celestia":
|
||||||
case "rootstock":
|
case "Rootstock":
|
||||||
case "stargaze":
|
case "Stargaze":
|
||||||
case "seda":
|
case "Seda":
|
||||||
case "dymension":
|
case "Dymension":
|
||||||
case "provenance":
|
case "Provenance":
|
||||||
throw new Error(`${chainName} not supported`);
|
throw new Error(`${chainName} not supported`);
|
||||||
default:
|
default:
|
||||||
impossible(chainName);
|
impossible(chainName);
|
||||||
|
|
|
@ -1,20 +1,3 @@
|
||||||
import {
|
|
||||||
CHAIN_ID_ALGORAND,
|
|
||||||
CHAIN_ID_APTOS,
|
|
||||||
CHAIN_ID_INJECTIVE,
|
|
||||||
CHAIN_ID_NEAR,
|
|
||||||
CHAIN_ID_SEI,
|
|
||||||
CHAIN_ID_SOLANA,
|
|
||||||
CHAIN_ID_SUI,
|
|
||||||
CHAIN_ID_TERRA,
|
|
||||||
CHAIN_ID_TERRA2,
|
|
||||||
CHAIN_ID_XPLA,
|
|
||||||
ChainId,
|
|
||||||
ChainName,
|
|
||||||
EVMChainId,
|
|
||||||
EVMChainName,
|
|
||||||
coalesceChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
|
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
|
||||||
import {
|
import {
|
||||||
Network as InjectiveNetwork,
|
Network as InjectiveNetwork,
|
||||||
|
@ -32,104 +15,107 @@ import { ethers } from "ethers";
|
||||||
import { connect } from "near-api-js";
|
import { connect } from "near-api-js";
|
||||||
import { Provider as NearProvider } from "near-api-js/lib/providers";
|
import { Provider as NearProvider } from "near-api-js/lib/providers";
|
||||||
import { NETWORKS } from "../../consts";
|
import { NETWORKS } from "../../consts";
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { impossible } from "../../vaa";
|
import { impossible } from "../../vaa";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
ChainId,
|
||||||
|
Network,
|
||||||
|
PlatformToChains,
|
||||||
|
chainIds,
|
||||||
|
toChain,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
export type ChainProvider<T extends ChainId | ChainName> = T extends
|
export type ChainProvider<T extends Chain> = T extends "Algorand"
|
||||||
| "algorand"
|
|
||||||
| typeof CHAIN_ID_ALGORAND
|
|
||||||
? Algodv2
|
? Algodv2
|
||||||
: T extends "aptos" | typeof CHAIN_ID_APTOS
|
: T extends "Aptos"
|
||||||
? AptosClient
|
? AptosClient
|
||||||
: T extends EVMChainName | EVMChainId
|
: T extends PlatformToChains<"Evm">
|
||||||
? ethers.providers.JsonRpcProvider
|
? ethers.providers.JsonRpcProvider
|
||||||
: T extends "injective" | typeof CHAIN_ID_INJECTIVE
|
: T extends "Injective"
|
||||||
? ChainGrpcWasmApi
|
? ChainGrpcWasmApi
|
||||||
: T extends "near" | typeof CHAIN_ID_NEAR
|
: T extends "Near"
|
||||||
? Promise<NearProvider>
|
? Promise<NearProvider>
|
||||||
: T extends
|
: T extends "Terra" | "Terra2"
|
||||||
| "terra"
|
|
||||||
| "terra2"
|
|
||||||
| typeof CHAIN_ID_TERRA
|
|
||||||
| typeof CHAIN_ID_TERRA2
|
|
||||||
? TerraLCDClient
|
? TerraLCDClient
|
||||||
: T extends "sei" | typeof CHAIN_ID_SEI
|
: T extends "Sei"
|
||||||
? Promise<CosmWasmClient>
|
? Promise<CosmWasmClient>
|
||||||
: T extends "solana" | typeof CHAIN_ID_SOLANA
|
: T extends "Solana"
|
||||||
? SolanaConnection
|
? SolanaConnection
|
||||||
: T extends "sui" | typeof CHAIN_ID_SUI
|
: T extends "Sui"
|
||||||
? JsonRpcProvider
|
? JsonRpcProvider
|
||||||
: T extends "xpla" | typeof CHAIN_ID_XPLA
|
: T extends "Xpla"
|
||||||
? XplaLCDClient
|
? XplaLCDClient
|
||||||
: never;
|
: never;
|
||||||
|
|
||||||
export const getProviderForChain = <T extends ChainId | ChainName>(
|
export const getProviderForChain = <T extends Chain>(
|
||||||
chain: T,
|
chain: T,
|
||||||
network: Network,
|
network: Network,
|
||||||
options?: { rpc?: string; [opt: string]: any }
|
options?: { rpc?: string; [opt: string]: any }
|
||||||
): ChainProvider<T> => {
|
): ChainProvider<T> => {
|
||||||
const chainName = coalesceChainName(chain);
|
const rpc = options?.rpc ?? NETWORKS[network][chain].rpc;
|
||||||
const rpc = options?.rpc ?? NETWORKS[network][chainName].rpc;
|
|
||||||
if (!rpc) {
|
if (!rpc) {
|
||||||
throw new Error(`No ${network} rpc defined for ${chainName}`);
|
throw new Error(`No ${network} rpc defined for ${chain}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (chainName) {
|
switch (chain) {
|
||||||
case "unset":
|
case "Solana":
|
||||||
throw new Error("Chain not set");
|
|
||||||
case "solana":
|
|
||||||
return new SolanaConnection(rpc, "confirmed") as ChainProvider<T>;
|
return new SolanaConnection(rpc, "confirmed") as ChainProvider<T>;
|
||||||
case "acala":
|
case "Acala":
|
||||||
case "arbitrum":
|
case "Arbitrum":
|
||||||
case "aurora":
|
case "Aurora":
|
||||||
case "avalanche":
|
case "Avalanche":
|
||||||
case "base":
|
case "Base":
|
||||||
case "bsc":
|
case "Bsc":
|
||||||
case "celo":
|
case "Celo":
|
||||||
case "ethereum":
|
case "Ethereum":
|
||||||
case "fantom":
|
case "Fantom":
|
||||||
case "gnosis":
|
case "Gnosis":
|
||||||
case "karura":
|
case "Karura":
|
||||||
case "klaytn":
|
case "Klaytn":
|
||||||
case "moonbeam":
|
case "Moonbeam":
|
||||||
case "neon":
|
case "Neon":
|
||||||
case "oasis":
|
case "Oasis":
|
||||||
case "optimism":
|
case "Optimism":
|
||||||
case "polygon":
|
case "Polygon":
|
||||||
// case "rootstock":
|
// case "Rootstock":
|
||||||
case "scroll":
|
case "Scroll":
|
||||||
case "mantle":
|
case "Mantle":
|
||||||
case "blast":
|
case "Blast":
|
||||||
case "xlayer":
|
case "Xlayer":
|
||||||
case "linea":
|
case "Linea":
|
||||||
case "berachain":
|
case "Berachain":
|
||||||
case "seievm":
|
case "Seievm":
|
||||||
case "sepolia":
|
case "Sepolia":
|
||||||
case "arbitrum_sepolia":
|
case "ArbitrumSepolia":
|
||||||
case "base_sepolia":
|
case "BaseSepolia":
|
||||||
case "optimism_sepolia":
|
case "OptimismSepolia":
|
||||||
case "polygon_sepolia":
|
case "PolygonSepolia":
|
||||||
case "holesky":
|
case "Holesky":
|
||||||
return new ethers.providers.JsonRpcProvider(rpc) as ChainProvider<T>;
|
return new ethers.providers.JsonRpcProvider(rpc) as ChainProvider<T>;
|
||||||
case "terra":
|
case "Terra":
|
||||||
case "terra2":
|
case "Terra2":
|
||||||
|
const chain_id =
|
||||||
|
chain === "Terra"
|
||||||
|
? NETWORKS[network].Terra.chain_id
|
||||||
|
: NETWORKS[network].Terra2.chain_id;
|
||||||
return new TerraLCDClient({
|
return new TerraLCDClient({
|
||||||
URL: rpc,
|
URL: rpc,
|
||||||
chainID: NETWORKS[network][chainName].chain_id,
|
chainID: chain_id,
|
||||||
isClassic: chainName === "terra",
|
isClassic: chain === "Terra",
|
||||||
}) as ChainProvider<T>;
|
}) as ChainProvider<T>;
|
||||||
case "injective": {
|
case "Injective": {
|
||||||
const endpoints = getNetworkEndpoints(
|
const endpoints = getNetworkEndpoints(
|
||||||
network === "MAINNET"
|
network === "Mainnet"
|
||||||
? InjectiveNetwork.MainnetK8s
|
? InjectiveNetwork.MainnetK8s
|
||||||
: InjectiveNetwork.TestnetK8s
|
: InjectiveNetwork.TestnetK8s
|
||||||
);
|
);
|
||||||
return new ChainGrpcWasmApi(endpoints.grpc) as ChainProvider<T>;
|
return new ChainGrpcWasmApi(endpoints.grpc) as ChainProvider<T>;
|
||||||
}
|
}
|
||||||
case "sei":
|
case "Sei":
|
||||||
return getCosmWasmClient(rpc) as ChainProvider<T>;
|
return getCosmWasmClient(rpc) as ChainProvider<T>;
|
||||||
case "xpla": {
|
case "Xpla": {
|
||||||
const chainId = NETWORKS[network].xpla.chain_id;
|
const chainId = NETWORKS[network].Xpla.chain_id;
|
||||||
if (!chainId) {
|
if (!chainId) {
|
||||||
throw new Error(`No ${network} chain ID defined for XPLA.`);
|
throw new Error(`No ${network} chain ID defined for XPLA.`);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +125,7 @@ export const getProviderForChain = <T extends ChainId | ChainName>(
|
||||||
chainID: chainId,
|
chainID: chainId,
|
||||||
}) as ChainProvider<T>;
|
}) as ChainProvider<T>;
|
||||||
}
|
}
|
||||||
case "algorand": {
|
case "Algorand": {
|
||||||
const { token, port } = {
|
const { token, port } = {
|
||||||
...{
|
...{
|
||||||
token:
|
token:
|
||||||
|
@ -150,34 +136,34 @@ export const getProviderForChain = <T extends ChainId | ChainName>(
|
||||||
};
|
};
|
||||||
return new Algodv2(token, rpc, port) as ChainProvider<T>;
|
return new Algodv2(token, rpc, port) as ChainProvider<T>;
|
||||||
}
|
}
|
||||||
case "near":
|
case "Near":
|
||||||
return connect({
|
return connect({
|
||||||
networkId: NETWORKS[network].near.networkId,
|
networkId: NETWORKS[network].Near.networkId,
|
||||||
nodeUrl: rpc,
|
nodeUrl: rpc,
|
||||||
headers: {},
|
headers: {},
|
||||||
}).then(({ connection }) => connection.provider) as ChainProvider<T>;
|
}).then(({ connection }) => connection.provider) as ChainProvider<T>;
|
||||||
case "aptos":
|
case "Aptos":
|
||||||
return new AptosClient(rpc) as ChainProvider<T>;
|
return new AptosClient(rpc) as ChainProvider<T>;
|
||||||
case "sui":
|
case "Sui":
|
||||||
return new JsonRpcProvider(
|
return new JsonRpcProvider(
|
||||||
new SuiConnection({ fullnode: rpc })
|
new SuiConnection({ fullnode: rpc })
|
||||||
) as ChainProvider<T>;
|
) as ChainProvider<T>;
|
||||||
case "btc":
|
case "Btc":
|
||||||
case "osmosis":
|
case "Osmosis":
|
||||||
case "pythnet":
|
case "Pythnet":
|
||||||
case "wormchain":
|
case "Wormchain":
|
||||||
case "cosmoshub":
|
case "Cosmoshub":
|
||||||
case "evmos":
|
case "Evmos":
|
||||||
case "kujira":
|
case "Kujira":
|
||||||
case "neutron":
|
case "Neutron":
|
||||||
case "celestia":
|
case "Celestia":
|
||||||
case "stargaze":
|
case "Stargaze":
|
||||||
case "seda":
|
case "Seda":
|
||||||
case "dymension":
|
case "Dymension":
|
||||||
case "provenance":
|
case "Provenance":
|
||||||
case "rootstock":
|
case "Rootstock":
|
||||||
throw new Error(`${chainName} not supported`);
|
throw new Error(`${chain} not supported`);
|
||||||
default:
|
default:
|
||||||
impossible(chainName);
|
impossible(chain);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,28 +1,22 @@
|
||||||
import { getCosmWasmClient } from "@sei-js/core";
|
import { getCosmWasmClient } from "@sei-js/core";
|
||||||
import {
|
|
||||||
ChainName,
|
|
||||||
CHAINS,
|
|
||||||
CONTRACTS,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { NETWORKS } from "../../consts/networks";
|
import { NETWORKS } from "../../consts/networks";
|
||||||
import { Network } from "../../utils";
|
import { Chain, Network, chains, contracts } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export async function queryRegistrationsSei(
|
export async function queryRegistrationsSei(
|
||||||
network: Network,
|
network: Network,
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge"
|
module: "Core" | "NFTBridge" | "TokenBridge"
|
||||||
): Promise<Object> {
|
): Promise<Object> {
|
||||||
const chain = "sei" as ChainName;
|
const chain: Chain = "Sei";
|
||||||
const n = NETWORKS[network][chain];
|
const n = NETWORKS[network][chain];
|
||||||
const contracts = CONTRACTS[network][chain];
|
|
||||||
|
|
||||||
let target_contract: string | undefined;
|
let target_contract: string | undefined;
|
||||||
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
target_contract = contracts.token_bridge;
|
target_contract = contracts.tokenBridge.get(network, chain);
|
||||||
break;
|
break;
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
target_contract = contracts.nft_bridge;
|
target_contract = contracts.nftBridge.get(network, chain);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid module: ${module}`);
|
throw new Error(`Invalid module: ${module}`);
|
||||||
|
@ -41,14 +35,14 @@ export async function queryRegistrationsSei(
|
||||||
|
|
||||||
// Query the bridge registration for all the chains in parallel.
|
// Query the bridge registration for all the chains in parallel.
|
||||||
const registrations = await Promise.all(
|
const registrations = await Promise.all(
|
||||||
Object.entries(CHAINS)
|
chains
|
||||||
.filter(([c_name, _]) => c_name !== chain && c_name !== "unset")
|
.filter((c_name) => c_name !== chain)
|
||||||
.map(async ([c_name, c_id]) => [
|
.map(async (c_name) => [
|
||||||
c_name,
|
c_name,
|
||||||
await (async () => {
|
await (async () => {
|
||||||
let query_msg = {
|
let query_msg = {
|
||||||
chain_registration: {
|
chain_registration: {
|
||||||
chain: c_id,
|
chain: c_name,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,13 @@ import {
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/cosmwasm/address";
|
} from "@certusone/wormhole-sdk/lib/esm/cosmwasm/address";
|
||||||
import { WormholeWrappedInfo } from "@certusone/wormhole-sdk/lib/esm/token_bridge/getOriginalAsset";
|
import { WormholeWrappedInfo } from "@certusone/wormhole-sdk/lib/esm/token_bridge/getOriginalAsset";
|
||||||
import { hexToUint8Array } from "@certusone/wormhole-sdk/lib/esm/utils/array";
|
import { hexToUint8Array } from "@certusone/wormhole-sdk/lib/esm/utils/array";
|
||||||
import {
|
|
||||||
CHAIN_ID_SEI,
|
|
||||||
ChainId,
|
|
||||||
ChainName,
|
|
||||||
coalesceChainId,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
|
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
ChainId,
|
||||||
|
chainToChainId,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk";
|
||||||
import { fromUint8Array } from "js-base64";
|
import { fromUint8Array } from "js-base64";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,7 @@ import { fromUint8Array } from "js-base64";
|
||||||
export async function getForeignAssetSei(
|
export async function getForeignAssetSei(
|
||||||
tokenBridgeAddress: string,
|
tokenBridgeAddress: string,
|
||||||
cosmwasmClient: CosmWasmClient,
|
cosmwasmClient: CosmWasmClient,
|
||||||
originChain: ChainId | ChainName,
|
originChain: ChainId | Chain,
|
||||||
originAsset: Uint8Array
|
originAsset: Uint8Array
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
try {
|
try {
|
||||||
|
@ -33,7 +33,7 @@ export async function getForeignAssetSei(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
{
|
{
|
||||||
wrapped_registry: {
|
wrapped_registry: {
|
||||||
chain: coalesceChainId(originChain),
|
chain: toChainId(originChain),
|
||||||
address: fromUint8Array(originAsset),
|
address: fromUint8Array(originAsset),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ export async function getOriginalAssetSei(
|
||||||
wrappedAddress: string,
|
wrappedAddress: string,
|
||||||
client: CosmWasmClient
|
client: CosmWasmClient
|
||||||
): Promise<WormholeWrappedInfo> {
|
): Promise<WormholeWrappedInfo> {
|
||||||
const chainId = CHAIN_ID_SEI;
|
const chainId = chainToChainId("Sei");
|
||||||
if (isNativeCosmWasmDenom(chainId, wrappedAddress)) {
|
if (isNativeCosmWasmDenom(chainId, wrappedAddress)) {
|
||||||
return {
|
return {
|
||||||
isWrapped: false,
|
isWrapped: false,
|
||||||
|
|
|
@ -5,10 +5,9 @@ import { toUtf8 } from "@cosmjs/encoding";
|
||||||
import { MsgExecuteContract } from "cosmjs-types/cosmwasm/wasm/v1/tx";
|
import { MsgExecuteContract } from "cosmjs-types/cosmwasm/wasm/v1/tx";
|
||||||
import { getSigningCosmWasmClient } from "@sei-js/core";
|
import { getSigningCosmWasmClient } from "@sei-js/core";
|
||||||
|
|
||||||
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { NETWORKS } from "../../consts";
|
import { NETWORKS } from "../../consts";
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { impossible, Payload } from "../../vaa";
|
import { impossible, Payload } from "../../vaa";
|
||||||
|
import { contracts, Network } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export const submit = async (
|
export const submit = async (
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
|
@ -16,8 +15,7 @@ export const submit = async (
|
||||||
network: Network,
|
network: Network,
|
||||||
rpc?: string
|
rpc?: string
|
||||||
) => {
|
) => {
|
||||||
const contracts = CONTRACTS[network].sei;
|
const networkInfo = NETWORKS[network].Sei;
|
||||||
const networkInfo = NETWORKS[network].sei;
|
|
||||||
rpc = rpc || networkInfo.rpc;
|
rpc = rpc || networkInfo.rpc;
|
||||||
const key = networkInfo.key;
|
const key = networkInfo.key;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
|
@ -32,12 +30,12 @@ export const submit = async (
|
||||||
let execute_msg: object;
|
let execute_msg: object;
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
if (!contracts.core) {
|
const core = contracts.coreBridge.get(network, "Sei");
|
||||||
|
if (!core) {
|
||||||
throw new Error(`Core bridge address not defined for Sei ${network}`);
|
throw new Error(`Core bridge address not defined for Sei ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.core;
|
target_contract = core;
|
||||||
// sigh...
|
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_v_a_a: {
|
submit_v_a_a: {
|
||||||
vaa: vaa.toString("base64"),
|
vaa: vaa.toString("base64"),
|
||||||
|
@ -59,14 +57,12 @@ export const submit = async (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "NFTBridge": {
|
case "NFTBridge": {
|
||||||
if (!contracts.nft_bridge) {
|
const nft = contracts.nftBridge.get(network, "Sei");
|
||||||
// NOTE: this code can safely be removed once the sei NFT bridge is
|
if (!nft) {
|
||||||
// released, but it's fine for it to stay, as the condition will just be
|
|
||||||
// skipped once 'contracts.nft_bridge' is defined
|
|
||||||
throw new Error("NFT bridge not supported yet for Sei");
|
throw new Error("NFT bridge not supported yet for Sei");
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.nft_bridge;
|
target_contract = nft;
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_vaa: {
|
submit_vaa: {
|
||||||
data: vaa.toString("base64"),
|
data: vaa.toString("base64"),
|
||||||
|
@ -91,11 +87,12 @@ export const submit = async (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
if (!contracts.token_bridge) {
|
const tb = contracts.tokenBridge.get(network, "Sei");
|
||||||
|
if (!tb) {
|
||||||
throw new Error(`Token bridge address not defined for Sei ${network}`);
|
throw new Error(`Token bridge address not defined for Sei ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.token_bridge;
|
target_contract = tb;
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_vaa: {
|
submit_vaa: {
|
||||||
data: vaa.toString("base64"),
|
data: vaa.toString("base64"),
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { JsonRpcProvider } from "@mysten/sui.js";
|
import { JsonRpcProvider } from "@mysten/sui.js";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { MoveToml } from "./MoveToml";
|
import { MoveToml } from "./MoveToml";
|
||||||
import {
|
import {
|
||||||
buildPackage,
|
buildPackage,
|
||||||
|
@ -12,6 +11,7 @@ import {
|
||||||
} from "./publish";
|
} from "./publish";
|
||||||
import { SuiBuildOutput } from "./types";
|
import { SuiBuildOutput } from "./types";
|
||||||
import { getPackageId } from "./utils";
|
import { getPackageId } from "./utils";
|
||||||
|
import { Network } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export const buildCoin = async (
|
export const buildCoin = async (
|
||||||
provider: JsonRpcProvider,
|
provider: JsonRpcProvider,
|
||||||
|
@ -93,8 +93,8 @@ const setupCoin = (
|
||||||
for (const dependencyPath of paths) {
|
for (const dependencyPath of paths) {
|
||||||
// todo(aki): the 4th param is a hack that makes this work, but doesn't
|
// todo(aki): the 4th param is a hack that makes this work, but doesn't
|
||||||
// necessarily make sense. We should probably revisit this later.
|
// necessarily make sense. We should probably revisit this later.
|
||||||
setupMainToml(dependencyPath, network, false, network !== "DEVNET");
|
setupMainToml(dependencyPath, network, false, network !== "Devnet");
|
||||||
if (network === "DEVNET") {
|
if (network === "Devnet") {
|
||||||
const dependencyToml = new MoveToml(getDefaultTomlPath(dependencyPath));
|
const dependencyToml = new MoveToml(getDefaultTomlPath(dependencyPath));
|
||||||
switch (getPackageNameFromPath(dependencyPath)) {
|
switch (getPackageNameFromPath(dependencyPath)) {
|
||||||
case "wormhole":
|
case "wormhole":
|
||||||
|
|
|
@ -8,10 +8,10 @@ import {
|
||||||
import { execSync } from "child_process";
|
import { execSync } from "child_process";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { resolve } from "path";
|
import { resolve } from "path";
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { MoveToml } from "./MoveToml";
|
import { MoveToml } from "./MoveToml";
|
||||||
import { SuiBuildOutput } from "./types";
|
import { SuiBuildOutput } from "./types";
|
||||||
import { executeTransactionBlock } from "./utils";
|
import { executeTransactionBlock } from "./utils";
|
||||||
|
import { Network } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export const buildPackage = (packagePath: string): SuiBuildOutput => {
|
export const buildPackage = (packagePath: string): SuiBuildOutput => {
|
||||||
if (!fs.existsSync(packagePath)) {
|
if (!fs.existsSync(packagePath)) {
|
||||||
|
@ -76,7 +76,7 @@ export const publishPackage = async (
|
||||||
|
|
||||||
// Publish contracts
|
// Publish contracts
|
||||||
const tx = new TransactionBlock();
|
const tx = new TransactionBlock();
|
||||||
if (network === "DEVNET") {
|
if (network === "Devnet") {
|
||||||
// Avoid Error checking transaction input objects: GasBudgetTooHigh { gas_budget: 50000000000, max_budget: 10000000000 }
|
// Avoid Error checking transaction input objects: GasBudgetTooHigh { gas_budget: 50000000000, max_budget: 10000000000 }
|
||||||
tx.setGasBudget(10000000000);
|
tx.setGasBudget(10000000000);
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ export const setupMainToml = (
|
||||||
// don't have to manually reset them repeatedly during local development.
|
// don't have to manually reset them repeatedly during local development.
|
||||||
// This is not recursive because we assume that packages are deployed bottom
|
// This is not recursive because we assume that packages are deployed bottom
|
||||||
// up.
|
// up.
|
||||||
if (!isDependency && network === "DEVNET") {
|
if (!isDependency && network === "Devnet") {
|
||||||
resetNetworkToml(packagePath, network);
|
resetNetworkToml(packagePath, network);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,24 @@
|
||||||
import { getObjectFields } from "@certusone/wormhole-sdk/lib/esm/sui";
|
import { getObjectFields } from "@certusone/wormhole-sdk/lib/esm/sui";
|
||||||
import {
|
|
||||||
CHAIN_ID_TO_NAME,
|
|
||||||
CONTRACTS,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { NETWORKS } from "../../consts/networks";
|
import { NETWORKS } from "../../consts/networks";
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { getProvider } from "./utils";
|
import { getProvider } from "./utils";
|
||||||
import { ChainId } from "@certusone/wormhole-sdk";
|
import {
|
||||||
|
ChainId,
|
||||||
|
Network,
|
||||||
|
chainIdToChain,
|
||||||
|
contracts,
|
||||||
|
} from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export async function queryRegistrationsSui(
|
export async function queryRegistrationsSui(
|
||||||
network: Network,
|
network: Network,
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge"
|
module: "Core" | "NFTBridge" | "TokenBridge"
|
||||||
): Promise<Object> {
|
): Promise<Object> {
|
||||||
const n = NETWORKS[network]["sui"];
|
const n = NETWORKS[network]["Sui"];
|
||||||
const provider = getProvider(network, n.rpc);
|
const provider = getProvider(network, n.rpc);
|
||||||
const contracts = CONTRACTS[network]["sui"];
|
|
||||||
let state_object_id: string;
|
let state_object_id: string;
|
||||||
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
state_object_id = contracts.token_bridge;
|
state_object_id = contracts.tokenBridge(network, "Sui");
|
||||||
if (state_object_id === undefined) {
|
if (state_object_id === undefined) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for Sui`);
|
throw Error(`Unknown token bridge contract on ${network} for Sui`);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +48,7 @@ export async function queryRegistrationsSui(
|
||||||
const emitterAddress: Uint8Array =
|
const emitterAddress: Uint8Array =
|
||||||
emitter.data?.content?.fields.value.fields.value.fields.data;
|
emitter.data?.content?.fields.value.fields.value.fields.data;
|
||||||
const emitterAddrStr = Buffer.from(emitterAddress).toString("hex");
|
const emitterAddrStr = Buffer.from(emitterAddress).toString("hex");
|
||||||
results[CHAIN_ID_TO_NAME[chainId]] = emitterAddrStr;
|
results[chainIdToChain(chainId)] = emitterAddrStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,7 @@ import {
|
||||||
createWrappedOnSui,
|
createWrappedOnSui,
|
||||||
createWrappedOnSuiPrepare,
|
createWrappedOnSuiPrepare,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/createWrapped";
|
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/createWrapped";
|
||||||
import { getForeignAssetSui } from "@certusone/wormhole-sdk/lib/esm/token_bridge/getForeignAsset";
|
|
||||||
import {
|
|
||||||
CHAIN_ID_SUI,
|
|
||||||
CHAIN_ID_TO_NAME,
|
|
||||||
CONTRACTS,
|
|
||||||
assertChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { parseAttestMetaVaa } from "@certusone/wormhole-sdk/lib/esm/vaa/tokenBridge";
|
|
||||||
import { SUI_CLOCK_OBJECT_ID, TransactionBlock } from "@mysten/sui.js";
|
import { SUI_CLOCK_OBJECT_ID, TransactionBlock } from "@mysten/sui.js";
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { Payload, impossible } from "../../vaa";
|
import { Payload, impossible } from "../../vaa";
|
||||||
import {
|
import {
|
||||||
assertSuccess,
|
assertSuccess,
|
||||||
|
@ -28,6 +19,15 @@ import {
|
||||||
registerChain,
|
registerChain,
|
||||||
setMaxGasBudgetDevnet,
|
setMaxGasBudgetDevnet,
|
||||||
} from "./utils";
|
} from "./utils";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
Network,
|
||||||
|
VAA,
|
||||||
|
assertChain,
|
||||||
|
contracts,
|
||||||
|
deserialize,
|
||||||
|
} from "@wormhole-foundation/sdk";
|
||||||
|
import { getForeignAssetSui } from "../../sdk/sui";
|
||||||
|
|
||||||
export const submit = async (
|
export const submit = async (
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
|
@ -39,13 +39,13 @@ export const submit = async (
|
||||||
const consoleWarnTemp = console.warn;
|
const consoleWarnTemp = console.warn;
|
||||||
console.warn = () => {};
|
console.warn = () => {};
|
||||||
|
|
||||||
const chain = CHAIN_ID_TO_NAME[CHAIN_ID_SUI];
|
const chain: Chain = "Sui";
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
const signer = getSigner(provider, network, privateKey);
|
const signer = getSigner(provider, network, privateKey);
|
||||||
|
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
const coreObjectId = CONTRACTS[network][chain].core;
|
const coreObjectId = contracts.coreBridge(network, chain);
|
||||||
if (!coreObjectId) {
|
if (!coreObjectId) {
|
||||||
throw Error("Core bridge object ID is undefined");
|
throw Error("Core bridge object ID is undefined");
|
||||||
}
|
}
|
||||||
|
@ -103,12 +103,12 @@ export const submit = async (
|
||||||
throw new Error("NFT bridge not supported on Sui");
|
throw new Error("NFT bridge not supported on Sui");
|
||||||
}
|
}
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
const coreBridgeStateObjectId = CONTRACTS[network][chain].core;
|
const coreBridgeStateObjectId = contracts.coreBridge(network, chain);
|
||||||
if (!coreBridgeStateObjectId) {
|
if (!coreBridgeStateObjectId) {
|
||||||
throw Error("Core bridge object ID is undefined");
|
throw Error("Core bridge object ID is undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenBridgeStateObjectId = CONTRACTS[network][chain].token_bridge;
|
const tokenBridgeStateObjectId = contracts.tokenBridge(network, chain);
|
||||||
if (!tokenBridgeStateObjectId) {
|
if (!tokenBridgeStateObjectId) {
|
||||||
throw Error("Token bridge object ID is undefined");
|
throw Error("Token bridge object ID is undefined");
|
||||||
}
|
}
|
||||||
|
@ -116,13 +116,19 @@ export const submit = async (
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "AttestMeta": {
|
case "AttestMeta": {
|
||||||
// Test attest VAA: 01000000000100d87023087588d8a482d6082c57f3c93649c9a61a98848fc3a0b271f4041394ff7b28abefc8e5e19b83f45243d073d677e122e41425c2dbae3eb5ae1c7c0ac0ee01000000c056a8000000020000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16000000000000000001020000000000000000000000002d8be6bf0baa74e0a907016679cae9190e80dd0a000212544b4e0000000000000000000000000000000000000000000000000000000000457468657265756d205465737420546f6b656e00000000000000000000000000
|
// Test attest VAA: 01000000000100d87023087588d8a482d6082c57f3c93649c9a61a98848fc3a0b271f4041394ff7b28abefc8e5e19b83f45243d073d677e122e41425c2dbae3eb5ae1c7c0ac0ee01000000c056a8000000020000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16000000000000000001020000000000000000000000002d8be6bf0baa74e0a907016679cae9190e80dd0a000212544b4e0000000000000000000000000000000000000000000000000000000000457468657265756d205465737420546f6b656e00000000000000000000000000
|
||||||
const { tokenChain, tokenAddress } = parseAttestMetaVaa(vaa);
|
const parsedAttest: VAA<"TokenBridge:AttestMeta"> = deserialize(
|
||||||
|
"TokenBridge:AttestMeta",
|
||||||
|
vaa
|
||||||
|
);
|
||||||
|
const tokenChain = parsedAttest.payload.token.chain;
|
||||||
assertChain(tokenChain);
|
assertChain(tokenChain);
|
||||||
|
const tokenAddress = parsedAttest.payload.token.address;
|
||||||
|
const decimals = parsedAttest.payload.decimals;
|
||||||
const coinType = await getForeignAssetSui(
|
const coinType = await getForeignAssetSui(
|
||||||
provider,
|
provider,
|
||||||
tokenBridgeStateObjectId,
|
tokenBridgeStateObjectId,
|
||||||
tokenChain,
|
tokenChain,
|
||||||
tokenAddress
|
tokenAddress.toUint8Array()
|
||||||
);
|
);
|
||||||
if (coinType) {
|
if (coinType) {
|
||||||
// Coin already exists, so we update it
|
// Coin already exists, so we update it
|
||||||
|
@ -135,7 +141,7 @@ export const submit = async (
|
||||||
provider,
|
provider,
|
||||||
coreBridgeStateObjectId,
|
coreBridgeStateObjectId,
|
||||||
tokenBridgeStateObjectId,
|
tokenBridgeStateObjectId,
|
||||||
parseAttestMetaVaa(vaa).decimals,
|
decimals,
|
||||||
await signer.getAddress()
|
await signer.getAddress()
|
||||||
);
|
);
|
||||||
setMaxGasBudgetDevnet(network, prepareTx);
|
setMaxGasBudgetDevnet(network, prepareTx);
|
||||||
|
@ -153,7 +159,7 @@ export const submit = async (
|
||||||
console.log(` Published to ${coinPackageId}`);
|
console.log(` Published to ${coinPackageId}`);
|
||||||
console.log(` Type ${getWrappedCoinType(coinPackageId)}`);
|
console.log(` Type ${getWrappedCoinType(coinPackageId)}`);
|
||||||
|
|
||||||
if (!rpc && network !== "DEVNET") {
|
if (!rpc && network !== "Devnet") {
|
||||||
// Wait for wrapped asset creation to be propagated to other
|
// Wait for wrapped asset creation to be propagated to other
|
||||||
// nodes in case this complete registration call is load balanced
|
// nodes in case this complete registration call is load balanced
|
||||||
// to another node.
|
// to another node.
|
||||||
|
|
|
@ -6,24 +6,26 @@ import {
|
||||||
setMaxGasBudgetDevnet,
|
setMaxGasBudgetDevnet,
|
||||||
} from "./utils";
|
} from "./utils";
|
||||||
import {
|
import {
|
||||||
CONTRACTS,
|
Chain,
|
||||||
ChainName,
|
|
||||||
Network,
|
Network,
|
||||||
tryNativeToUint8Array,
|
chainToChainId,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils";
|
contracts,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { tryNativeToUint8Array } from "../../sdk/array";
|
||||||
|
|
||||||
export async function transferSui(
|
export async function transferSui(
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
network: Network,
|
network: Network,
|
||||||
rpc: string
|
rpc: string
|
||||||
) {
|
) {
|
||||||
const { core, token_bridge } = CONTRACTS[network]["sui"];
|
const core = contracts.coreBridge(network, "Sui");
|
||||||
if (!core) {
|
if (!core) {
|
||||||
throw Error("Core bridge object ID is undefined");
|
throw Error("Core bridge object ID is undefined");
|
||||||
}
|
}
|
||||||
|
const token_bridge = contracts.tokenBridge.get(network, "Sui");
|
||||||
if (!token_bridge) {
|
if (!token_bridge) {
|
||||||
throw new Error("Token bridge object ID is undefined");
|
throw new Error("Token bridge object ID is undefined");
|
||||||
}
|
}
|
||||||
|
@ -44,8 +46,8 @@ export async function transferSui(
|
||||||
coins,
|
coins,
|
||||||
coinType,
|
coinType,
|
||||||
BigInt(amount),
|
BigInt(amount),
|
||||||
dstChain,
|
chainToChainId(dstChain),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain)
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain))
|
||||||
);
|
);
|
||||||
setMaxGasBudgetDevnet(network, tx);
|
setMaxGasBudgetDevnet(network, tx);
|
||||||
const result = await executeTransactionBlock(signer, tx);
|
const result = await executeTransactionBlock(signer, tx);
|
||||||
|
|
|
@ -13,9 +13,10 @@ import {
|
||||||
} from "@mysten/sui.js";
|
} from "@mysten/sui.js";
|
||||||
import { DynamicFieldPage } from "@mysten/sui.js/dist/types/dynamic_fields";
|
import { DynamicFieldPage } from "@mysten/sui.js/dist/types/dynamic_fields";
|
||||||
import { NETWORKS } from "../../consts";
|
import { NETWORKS } from "../../consts";
|
||||||
import { Network } from "../../utils";
|
|
||||||
import { Payload, VAA, parse, serialiseVAA } from "../../vaa";
|
import { Payload, VAA, parse, serialiseVAA } from "../../vaa";
|
||||||
import { SuiRpcValidationError } from "./error";
|
import { SuiRpcValidationError } from "./error";
|
||||||
|
import { Network } from "@wormhole-foundation/sdk";
|
||||||
|
import { isValidSuiAddress } from "../../sdk/sui";
|
||||||
|
|
||||||
const UPGRADE_CAP_TYPE = "0x2::package::UpgradeCap";
|
const UPGRADE_CAP_TYPE = "0x2::package::UpgradeCap";
|
||||||
|
|
||||||
|
@ -207,7 +208,7 @@ export const getProvider = (
|
||||||
throw new Error("Must provide network or RPC to initialize provider");
|
throw new Error("Must provide network or RPC to initialize provider");
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc = rpc || NETWORKS[network!].sui.rpc;
|
rpc = rpc || NETWORKS[network!].Sui.rpc;
|
||||||
if (!rpc) {
|
if (!rpc) {
|
||||||
throw new Error(`No default RPC found for Sui ${network}`);
|
throw new Error(`No default RPC found for Sui ${network}`);
|
||||||
}
|
}
|
||||||
|
@ -235,7 +236,7 @@ export const getSigner = (
|
||||||
customPrivateKey?: string
|
customPrivateKey?: string
|
||||||
): RawSigner => {
|
): RawSigner => {
|
||||||
const privateKey: string | undefined =
|
const privateKey: string | undefined =
|
||||||
customPrivateKey || NETWORKS[network].sui.key;
|
customPrivateKey || NETWORKS[network].Sui.key;
|
||||||
if (!privateKey) {
|
if (!privateKey) {
|
||||||
throw new Error(`No private key found for Sui ${network}`);
|
throw new Error(`No private key found for Sui ${network}`);
|
||||||
}
|
}
|
||||||
|
@ -323,9 +324,6 @@ export const isSuiPublishEvent = <
|
||||||
event: T
|
event: T
|
||||||
): event is K => event?.type === "published";
|
): event is K => event?.type === "published";
|
||||||
|
|
||||||
export const isValidSuiAddress = (objectId: string): boolean =>
|
|
||||||
/^(0x)?[0-9a-f]{1,64}$/.test(objectId);
|
|
||||||
|
|
||||||
// todo(aki): this needs to correctly handle types such as
|
// todo(aki): this needs to correctly handle types such as
|
||||||
// 0x2::dynamic_field::Field<0x3c6d386861470e6f9cb35f3c91f69e6c1f1737bd5d217ca06a15f582e1dc1ce3::state::MigrationControl, bool>
|
// 0x2::dynamic_field::Field<0x3c6d386861470e6f9cb35f3c91f69e6c1f1737bd5d217ca06a15f582e1dc1ce3::state::MigrationControl, bool>
|
||||||
export const normalizeSuiType = (type: string): string => {
|
export const normalizeSuiType = (type: string): string => {
|
||||||
|
@ -345,7 +343,7 @@ export const registerChain = async (
|
||||||
tokenBridgeStateObjectId: string,
|
tokenBridgeStateObjectId: string,
|
||||||
transactionBlock?: TransactionBlock
|
transactionBlock?: TransactionBlock
|
||||||
): Promise<TransactionBlock> => {
|
): Promise<TransactionBlock> => {
|
||||||
if (network === "DEVNET") {
|
if (network === "Devnet") {
|
||||||
// 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
|
||||||
|
@ -418,7 +416,7 @@ export const setMaxGasBudgetDevnet = (
|
||||||
network: Network,
|
network: Network,
|
||||||
tx: TransactionBlock
|
tx: TransactionBlock
|
||||||
) => {
|
) => {
|
||||||
if (network === "DEVNET") {
|
if (network === "Devnet") {
|
||||||
// Avoid Error checking transaction input objects: GasBudgetTooHigh { gas_budget: 50000000000, max_budget: 10000000000 }
|
// Avoid Error checking transaction input objects: GasBudgetTooHigh { gas_budget: 50000000000, max_budget: 10000000000 }
|
||||||
tx.setGasBudget(10000000000);
|
tx.setGasBudget(10000000000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
import { APTOS_DEPLOYER_ADDRESS_DEVNET } from "@certusone/wormhole-sdk";
|
|
||||||
import {
|
|
||||||
assertChain,
|
|
||||||
CHAIN_ID_APTOS,
|
|
||||||
coalesceChainId,
|
|
||||||
CONTRACTS,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { BCS, FaucetClient } from "aptos";
|
import { BCS, FaucetClient } from "aptos";
|
||||||
import { spawnSync } from "child_process";
|
import { spawnSync } from "child_process";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
@ -25,13 +18,23 @@ import {
|
||||||
RPC_OPTIONS,
|
RPC_OPTIONS,
|
||||||
} from "../consts";
|
} from "../consts";
|
||||||
import { runCommand, VALIDATOR_OPTIONS } from "../startValidator";
|
import { runCommand, VALIDATOR_OPTIONS } from "../startValidator";
|
||||||
import { assertNetwork, checkBinary, evm_address, hex } from "../utils";
|
import { checkBinary, evm_address, getNetwork, hex } from "../utils";
|
||||||
|
import {
|
||||||
|
assertChain,
|
||||||
|
chainToChainId,
|
||||||
|
contracts,
|
||||||
|
toChain,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
const APTOS_NODE_URL = "http://0.0.0.0:8080/v1";
|
const APTOS_NODE_URL = "http://0.0.0.0:8080/v1";
|
||||||
const APTOS_FAUCET_URL = "http://0.0.0.0:8081";
|
const APTOS_FAUCET_URL = "http://0.0.0.0:8081";
|
||||||
const README_URL =
|
const README_URL =
|
||||||
"https://github.com/wormhole-foundation/wormhole/blob/main/aptos/README.md";
|
"https://github.com/wormhole-foundation/wormhole/blob/main/aptos/README.md";
|
||||||
|
|
||||||
|
export const APTOS_DEPLOYER_ADDRESS_DEVNET =
|
||||||
|
"277fa055b6a73c42c0662d5236c65c864ccbf2d4abd21f174a30c8b786eab84b";
|
||||||
|
|
||||||
interface Package {
|
interface Package {
|
||||||
meta_file: string;
|
meta_file: string;
|
||||||
mv_files: string[];
|
mv_files: string[];
|
||||||
|
@ -56,12 +59,11 @@ export const builder = (y: typeof yargs) =>
|
||||||
(yargs) =>
|
(yargs) =>
|
||||||
yargs.option("network", NETWORK_OPTIONS).option("rpc", RPC_OPTIONS),
|
yargs.option("network", NETWORK_OPTIONS).option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const contract_address = evm_address(
|
const contract_address = evm_address(
|
||||||
CONTRACTS[network].aptos.token_bridge
|
contracts.tokenBridge(network, "Aptos")
|
||||||
);
|
);
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].aptos.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc;
|
||||||
await callEntryFunc(
|
await callEntryFunc(
|
||||||
network,
|
network,
|
||||||
rpc,
|
rpc,
|
||||||
|
@ -82,7 +84,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
.option("chain-id", {
|
.option("chain-id", {
|
||||||
describe: "Chain id",
|
describe: "Chain id",
|
||||||
type: "number",
|
type: "number",
|
||||||
default: CHAIN_ID_APTOS,
|
default: chainToChainId("Aptos"),
|
||||||
demandOption: false,
|
demandOption: false,
|
||||||
})
|
})
|
||||||
.option("governance-chain-id", {
|
.option("governance-chain-id", {
|
||||||
|
@ -104,10 +106,11 @@ export const builder = (y: typeof yargs) =>
|
||||||
type: "string",
|
type: "string",
|
||||||
}),
|
}),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
|
|
||||||
const contract_address = evm_address(CONTRACTS[network].aptos.core);
|
const contract_address = evm_address(
|
||||||
|
contracts.coreBridge(network, "Aptos")
|
||||||
|
);
|
||||||
const guardian_addresses = argv["guardian-address"]
|
const guardian_addresses = argv["guardian-address"]
|
||||||
.split(",")
|
.split(",")
|
||||||
.map((address) => evm_address(address).substring(24));
|
.map((address) => evm_address(address).substring(24));
|
||||||
|
@ -127,7 +130,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
BCS.bcsSerializeBytes(Buffer.from(governance_address, "hex")),
|
BCS.bcsSerializeBytes(Buffer.from(governance_address, "hex")),
|
||||||
guardians_serializer.getBytes(),
|
guardians_serializer.getBytes(),
|
||||||
];
|
];
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].aptos.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc;
|
||||||
await callEntryFunc(
|
await callEntryFunc(
|
||||||
network,
|
network,
|
||||||
rpc,
|
rpc,
|
||||||
|
@ -152,12 +155,11 @@ export const builder = (y: typeof yargs) =>
|
||||||
.option("rpc", RPC_OPTIONS)
|
.option("rpc", RPC_OPTIONS)
|
||||||
.option("named-addresses", NAMED_ADDRESSES_OPTIONS),
|
.option("named-addresses", NAMED_ADDRESSES_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
checkBinary("aptos", README_URL);
|
checkBinary("aptos", README_URL);
|
||||||
const p = buildPackage(argv["package-dir"], argv["named-addresses"]);
|
const p = buildPackage(argv["package-dir"], argv["named-addresses"]);
|
||||||
const b = serializePackage(p);
|
const b = serializePackage(p);
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].aptos.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc;
|
||||||
await callEntryFunc(
|
await callEntryFunc(
|
||||||
network,
|
network,
|
||||||
rpc,
|
rpc,
|
||||||
|
@ -188,21 +190,18 @@ export const builder = (y: typeof yargs) =>
|
||||||
.option("rpc", RPC_OPTIONS)
|
.option("rpc", RPC_OPTIONS)
|
||||||
.option("named-addresses", NAMED_ADDRESSES_OPTIONS),
|
.option("named-addresses", NAMED_ADDRESSES_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
checkBinary("aptos", README_URL);
|
checkBinary("aptos", README_URL);
|
||||||
const p = buildPackage(argv["package-dir"], argv["named-addresses"]);
|
const p = buildPackage(argv["package-dir"], argv["named-addresses"]);
|
||||||
const b = serializePackage(p);
|
const b = serializePackage(p);
|
||||||
const seed = Buffer.from(argv["seed"], "ascii");
|
const seed = Buffer.from(argv["seed"], "ascii");
|
||||||
|
|
||||||
// TODO(csongor): use deployer address from sdk (when it's there)
|
let module_name = APTOS_DEPLOYER_ADDRESS_DEVNET + "::deployer";
|
||||||
let module_name =
|
if (network == "Testnet" || network == "Mainnet") {
|
||||||
"0x277fa055b6a73c42c0662d5236c65c864ccbf2d4abd21f174a30c8b786eab84b::deployer";
|
|
||||||
if (network == "TESTNET" || network == "MAINNET") {
|
|
||||||
module_name =
|
module_name =
|
||||||
"0x0108bc32f7de18a5f6e1e7d6ee7aff9f5fc858d0d87ac0da94dd8d2a5d267d6b::deployer";
|
"0x0108bc32f7de18a5f6e1e7d6ee7aff9f5fc858d0d87ac0da94dd8d2a5d267d6b::deployer";
|
||||||
}
|
}
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].aptos.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc;
|
||||||
await callEntryFunc(
|
await callEntryFunc(
|
||||||
network,
|
network,
|
||||||
rpc,
|
rpc,
|
||||||
|
@ -226,13 +225,10 @@ export const builder = (y: typeof yargs) =>
|
||||||
})
|
})
|
||||||
.option("network", NETWORK_OPTIONS),
|
.option("network", NETWORK_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
const rpc = NETWORKS[network].Aptos.rpc;
|
||||||
const rpc = NETWORKS[network].aptos.rpc;
|
let module_name = APTOS_DEPLOYER_ADDRESS_DEVNET + "::sender";
|
||||||
// TODO(csongor): use sdk address
|
if (network == "Testnet" || network == "Mainnet") {
|
||||||
let module_name =
|
|
||||||
"0x277fa055b6a73c42c0662d5236c65c864ccbf2d4abd21f174a30c8b786eab84b::sender";
|
|
||||||
if (network == "TESTNET" || network == "MAINNET") {
|
|
||||||
module_name =
|
module_name =
|
||||||
"0x0108bc32f7de18a5f6e1e7d6ee7aff9f5fc858d0d87ac0da94dd8d2a5d267d6b::sender";
|
"0x0108bc32f7de18a5f6e1e7d6ee7aff9f5fc858d0d87ac0da94dd8d2a5d267d6b::sender";
|
||||||
}
|
}
|
||||||
|
@ -287,13 +283,12 @@ export const builder = (y: typeof yargs) =>
|
||||||
})
|
})
|
||||||
.option("network", NETWORK_OPTIONS),
|
.option("network", NETWORK_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
let address: string = contracts.tokenBridge(network, "Aptos");
|
||||||
let address = CONTRACTS[network].aptos.token_bridge;
|
|
||||||
if (address.startsWith("0x")) address = address.substring(2);
|
if (address.startsWith("0x")) address = address.substring(2);
|
||||||
const token_bridge_address = Buffer.from(address, "hex");
|
const token_bridge_address = Buffer.from(address, "hex");
|
||||||
assertChain(argv.chain);
|
assertChain(toChain(argv.chain));
|
||||||
const chain = coalesceChainId(argv.chain);
|
const chain = toChainId(argv.chain);
|
||||||
const origin_address = Buffer.from(
|
const origin_address = Buffer.from(
|
||||||
evm_address(argv["origin-address"]),
|
evm_address(argv["origin-address"]),
|
||||||
"hex"
|
"hex"
|
||||||
|
@ -343,12 +338,11 @@ export const builder = (y: typeof yargs) =>
|
||||||
.option("rpc", RPC_OPTIONS)
|
.option("rpc", RPC_OPTIONS)
|
||||||
.option("named-addresses", NAMED_ADDRESSES_OPTIONS),
|
.option("named-addresses", NAMED_ADDRESSES_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
checkBinary("aptos", README_URL);
|
checkBinary("aptos", README_URL);
|
||||||
const p = buildPackage(argv["package-dir"], argv["named-addresses"]);
|
const p = buildPackage(argv["package-dir"], argv["named-addresses"]);
|
||||||
const b = serializePackage(p);
|
const b = serializePackage(p);
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].aptos.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc;
|
||||||
// TODO(csongor): use deployer address from sdk (when it's there)
|
// TODO(csongor): use deployer address from sdk (when it's there)
|
||||||
const hash = await callEntryFunc(
|
const hash = await callEntryFunc(
|
||||||
network,
|
network,
|
||||||
|
@ -378,10 +372,9 @@ export const builder = (y: typeof yargs) =>
|
||||||
.option("network", NETWORK_OPTIONS)
|
.option("network", NETWORK_OPTIONS)
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
checkBinary("aptos", README_URL);
|
checkBinary("aptos", README_URL);
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].aptos.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc;
|
||||||
// TODO(csongor): use deployer address from sdk (when it's there)
|
// TODO(csongor): use deployer address from sdk (when it's there)
|
||||||
const hash = await callEntryFunc(
|
const hash = await callEntryFunc(
|
||||||
network,
|
network,
|
||||||
|
|
|
@ -17,14 +17,14 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import { Implementation__factory } from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
|
import { Implementation__factory } from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
|
||||||
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { Other } from "@certusone/wormhole-sdk/lib/esm/vaa";
|
import { Other } from "@certusone/wormhole-sdk/lib/esm/vaa";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { NETWORK_OPTIONS, NETWORKS } from "../consts";
|
import { NETWORK_OPTIONS, NETWORKS } from "../consts";
|
||||||
import { assertNetwork, Network } from "../utils";
|
|
||||||
import { parse, Payload, serialiseVAA, sign, Signature, VAA } from "../vaa";
|
import { parse, Payload, serialiseVAA, sign, Signature, VAA } from "../vaa";
|
||||||
|
import { contracts, Network } from "@wormhole-foundation/sdk-base";
|
||||||
|
import { getNetwork } from "../utils";
|
||||||
|
|
||||||
export const command = "edit-vaa";
|
export const command = "edit-vaa";
|
||||||
export const desc = "Edits or generates a VAA";
|
export const desc = "Edits or generates a VAA";
|
||||||
|
@ -102,8 +102,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
||||||
) => {
|
) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
|
|
||||||
let numSigs = 0;
|
let numSigs = 0;
|
||||||
if (argv.signatures) {
|
if (argv.signatures) {
|
||||||
|
@ -235,8 +234,8 @@ const getGuardianSet = async (
|
||||||
network: Network,
|
network: Network,
|
||||||
guardianSetIndex: number
|
guardianSetIndex: number
|
||||||
): Promise<string[]> => {
|
): Promise<string[]> => {
|
||||||
let n = NETWORKS[network].ethereum;
|
let n = NETWORKS[network].Ethereum;
|
||||||
let contract_address = CONTRACTS[network].ethereum.core;
|
let contract_address = contracts.coreBridge(network, "Ethereum");
|
||||||
if (contract_address === undefined) {
|
if (contract_address === undefined) {
|
||||||
throw Error(`Unknown core contract on ${network} for ethereum`);
|
throw Error(`Unknown core contract on ${network} for ethereum`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
import {
|
|
||||||
assertChain,
|
|
||||||
assertEVMChain,
|
|
||||||
ChainName,
|
|
||||||
CHAINS,
|
|
||||||
CONTRACTS,
|
|
||||||
isEVMChain,
|
|
||||||
toChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { homedir } from "os";
|
import { homedir } from "os";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
|
@ -18,7 +9,18 @@ import {
|
||||||
setStorageAt,
|
setStorageAt,
|
||||||
} from "../evm";
|
} from "../evm";
|
||||||
import { runCommand, VALIDATOR_OPTIONS } from "../startValidator";
|
import { runCommand, VALIDATOR_OPTIONS } from "../startValidator";
|
||||||
import { assertNetwork, evm_address } from "../utils";
|
import {
|
||||||
|
assertEVMChain,
|
||||||
|
chainToChain,
|
||||||
|
evm_address,
|
||||||
|
getNetwork,
|
||||||
|
} from "../utils";
|
||||||
|
import {
|
||||||
|
assertChain,
|
||||||
|
chains,
|
||||||
|
contracts,
|
||||||
|
platformToChains,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
export const command = "evm";
|
export const command = "evm";
|
||||||
export const desc = "EVM utilities";
|
export const desc = "EVM utilities";
|
||||||
|
@ -81,12 +83,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.command("chains", "Return all EVM chains", async (_) => {
|
.command("chains", "Return all EVM chains", async (_) => {
|
||||||
console.log(
|
console.log(...platformToChains("Evm"));
|
||||||
Object.values(CHAINS)
|
|
||||||
.map((id) => toChainName(id))
|
|
||||||
.filter((name) => isEVMChain(name))
|
|
||||||
.join(" ")
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.command(
|
.command(
|
||||||
"info",
|
"info",
|
||||||
|
@ -96,7 +93,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
.option("chain", {
|
.option("chain", {
|
||||||
alias: "c",
|
alias: "c",
|
||||||
describe: "Chain to query",
|
describe: "Chain to query",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.option("module", {
|
.option("module", {
|
||||||
|
@ -120,11 +117,9 @@ export const builder = function (y: typeof yargs) {
|
||||||
demandOption: false,
|
demandOption: false,
|
||||||
}),
|
}),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const chain = argv.chain;
|
const chain = chainToChain(argv.chain);
|
||||||
assertChain(chain);
|
|
||||||
assertEVMChain(chain);
|
assertEVMChain(chain);
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const module = argv.module;
|
const module = argv.module;
|
||||||
const rpc = argv.rpc ?? NETWORKS[network][chain].rpc;
|
const rpc = argv.rpc ?? NETWORKS[network][chain].rpc;
|
||||||
if (argv["implementation-only"]) {
|
if (argv["implementation-only"]) {
|
||||||
|
@ -163,7 +158,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
alias: "a",
|
alias: "a",
|
||||||
describe: "Core contract address",
|
describe: "Core contract address",
|
||||||
type: "string",
|
type: "string",
|
||||||
default: CONTRACTS.MAINNET.ethereum.core,
|
default: contracts.coreBridge("Mainnet", "Ethereum"),
|
||||||
})
|
})
|
||||||
.option("guardian-address", {
|
.option("guardian-address", {
|
||||||
alias: "g",
|
alias: "g",
|
||||||
|
@ -180,7 +175,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
}),
|
}),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const guardian_addresses = argv["guardian-address"].split(",");
|
const guardian_addresses = argv["guardian-address"].split(",");
|
||||||
let rpc = argv.rpc ?? NETWORKS.DEVNET.ethereum.rpc;
|
let rpc = argv.rpc ?? NETWORKS.Devnet.Ethereum.rpc;
|
||||||
await hijack_evm(
|
await hijack_evm(
|
||||||
rpc,
|
rpc,
|
||||||
argv["core-contract-address"],
|
argv["core-contract-address"],
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
import { tryNativeToHexString } from "@certusone/wormhole-sdk/lib/esm/utils/array";
|
|
||||||
import {
|
|
||||||
assertChain,
|
|
||||||
ChainName,
|
|
||||||
CHAINS,
|
|
||||||
isCosmWasmChain,
|
|
||||||
isEVMChain,
|
|
||||||
toChainId,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { fromBech32, toHex } from "@cosmjs/encoding";
|
import { fromBech32, toHex } from "@cosmjs/encoding";
|
||||||
import base58 from "bs58";
|
import base58 from "bs58";
|
||||||
import { sha3_256 } from "js-sha3";
|
import { sha3_256 } from "js-sha3";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { GOVERNANCE_CHAIN, GOVERNANCE_EMITTER } from "../consts";
|
import { GOVERNANCE_CHAIN, GOVERNANCE_EMITTER } from "../consts";
|
||||||
import { evm_address } from "../utils";
|
import { chainToChain, evm_address } from "../utils";
|
||||||
import {
|
import {
|
||||||
ContractUpgrade,
|
ContractUpgrade,
|
||||||
impossible,
|
|
||||||
Payload,
|
Payload,
|
||||||
PortalRegisterChain,
|
PortalRegisterChain,
|
||||||
RecoverChainId,
|
RecoverChainId,
|
||||||
|
@ -25,6 +15,13 @@ import {
|
||||||
VAA,
|
VAA,
|
||||||
WormholeRelayerSetDefaultDeliveryProvider,
|
WormholeRelayerSetDefaultDeliveryProvider,
|
||||||
} from "../vaa";
|
} from "../vaa";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
assertChain,
|
||||||
|
chainToPlatform,
|
||||||
|
chains,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
function makeVAA(
|
function makeVAA(
|
||||||
emitterChain: number,
|
emitterChain: number,
|
||||||
|
@ -68,7 +65,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
.option("chain", {
|
.option("chain", {
|
||||||
alias: "c",
|
alias: "c",
|
||||||
describe: "Chain to register",
|
describe: "Chain to register",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.option("contract-address", {
|
.option("contract-address", {
|
||||||
|
@ -85,13 +82,13 @@ export const builder = function (y: typeof yargs) {
|
||||||
} as const),
|
} as const),
|
||||||
(argv) => {
|
(argv) => {
|
||||||
const module = argv["module"];
|
const module = argv["module"];
|
||||||
assertChain(argv.chain);
|
const chain = chainToChain(argv.chain);
|
||||||
const payload: PortalRegisterChain<typeof module> = {
|
const payload: PortalRegisterChain<typeof module> = {
|
||||||
module,
|
module,
|
||||||
type: "RegisterChain",
|
type: "RegisterChain",
|
||||||
chain: 0,
|
chain: 0,
|
||||||
emitterChain: toChainId(argv.chain),
|
emitterChain: toChainId(chain),
|
||||||
emitterAddress: parseAddress(argv.chain, argv["contract-address"]),
|
emitterAddress: parseAddress(chain, argv["contract-address"]),
|
||||||
};
|
};
|
||||||
const vaa = makeVAA(
|
const vaa = makeVAA(
|
||||||
GOVERNANCE_CHAIN,
|
GOVERNANCE_CHAIN,
|
||||||
|
@ -111,7 +108,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
.option("chain", {
|
.option("chain", {
|
||||||
alias: "c",
|
alias: "c",
|
||||||
describe: "Chain to upgrade",
|
describe: "Chain to upgrade",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.option("contract-address", {
|
.option("contract-address", {
|
||||||
|
@ -127,13 +124,13 @@ export const builder = function (y: typeof yargs) {
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const),
|
} as const),
|
||||||
(argv) => {
|
(argv) => {
|
||||||
assertChain(argv.chain);
|
const chain = chainToChain(argv.chain);
|
||||||
const module = argv["module"];
|
const module = argv["module"];
|
||||||
const payload: ContractUpgrade = {
|
const payload: ContractUpgrade = {
|
||||||
module,
|
module,
|
||||||
type: "ContractUpgrade",
|
type: "ContractUpgrade",
|
||||||
chain: toChainId(argv.chain),
|
chain: toChainId(chain),
|
||||||
address: parseCodeAddress(argv.chain, argv["contract-address"]),
|
address: parseCodeAddress(chain, argv["contract-address"]),
|
||||||
};
|
};
|
||||||
const vaa = makeVAA(
|
const vaa = makeVAA(
|
||||||
GOVERNANCE_CHAIN,
|
GOVERNANCE_CHAIN,
|
||||||
|
@ -152,7 +149,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
.option("emitter-chain", {
|
.option("emitter-chain", {
|
||||||
alias: "e",
|
alias: "e",
|
||||||
describe: "Emitter chain of the VAA",
|
describe: "Emitter chain of the VAA",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.option("emitter-address", {
|
.option("emitter-address", {
|
||||||
|
@ -164,7 +161,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
.option("chain", {
|
.option("chain", {
|
||||||
alias: "c",
|
alias: "c",
|
||||||
describe: "Token's chain",
|
describe: "Token's chain",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.option("token-address", {
|
.option("token-address", {
|
||||||
|
@ -192,15 +189,14 @@ export const builder = function (y: typeof yargs) {
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
}),
|
}),
|
||||||
(argv) => {
|
(argv) => {
|
||||||
const emitter_chain = argv["emitter-chain"];
|
const emitter_chain = chainToChain(argv["emitter-chain"]);
|
||||||
assertChain(argv.chain);
|
const chain = chainToChain(argv.chain);
|
||||||
assertChain(emitter_chain);
|
|
||||||
const payload: TokenBridgeAttestMeta = {
|
const payload: TokenBridgeAttestMeta = {
|
||||||
module: "TokenBridge",
|
module: "TokenBridge",
|
||||||
type: "AttestMeta",
|
type: "AttestMeta",
|
||||||
chain: 0,
|
chain: 0,
|
||||||
tokenAddress: parseAddress(argv.chain, argv["token-address"]),
|
tokenAddress: parseAddress(chain, argv["token-address"]),
|
||||||
tokenChain: toChainId(argv.chain),
|
tokenChain: toChainId(chain),
|
||||||
decimals: argv["decimals"],
|
decimals: argv["decimals"],
|
||||||
symbol: argv["symbol"],
|
symbol: argv["symbol"],
|
||||||
name: argv["name"],
|
name: argv["name"],
|
||||||
|
@ -263,7 +259,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
.option("chain", {
|
.option("chain", {
|
||||||
alias: "c",
|
alias: "c",
|
||||||
describe: "Chain of Wormhole Relayer contract",
|
describe: "Chain of Wormhole Relayer contract",
|
||||||
choices: Object.keys(CHAINS),
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.option("delivery-provider-address", {
|
.option("delivery-provider-address", {
|
||||||
|
@ -274,13 +270,13 @@ export const builder = function (y: typeof yargs) {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
(argv) => {
|
(argv) => {
|
||||||
assertChain(argv.chain);
|
const chain = chainToChain(argv.chain);
|
||||||
const payload: WormholeRelayerSetDefaultDeliveryProvider = {
|
const payload: WormholeRelayerSetDefaultDeliveryProvider = {
|
||||||
module: "WormholeRelayer",
|
module: "WormholeRelayer",
|
||||||
type: "SetDefaultDeliveryProvider",
|
type: "SetDefaultDeliveryProvider",
|
||||||
chain: toChainId(argv["chain"]),
|
chain: toChainId(chain),
|
||||||
relayProviderAddress: parseAddress(
|
relayProviderAddress: parseAddress(
|
||||||
argv["chain"],
|
chain,
|
||||||
argv["delivery-provider-address"]
|
argv["delivery-provider-address"]
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
@ -297,45 +293,43 @@ export const builder = function (y: typeof yargs) {
|
||||||
};
|
};
|
||||||
export const handler = () => {};
|
export const handler = () => {};
|
||||||
|
|
||||||
function parseAddress(chain: ChainName, address: string): string {
|
function parseAddress(chain: Chain, address: string): string {
|
||||||
if (chain === "unset") {
|
if (chainToPlatform(chain) === "Evm") {
|
||||||
throw Error("Chain unset");
|
|
||||||
} else if (isEVMChain(chain)) {
|
|
||||||
return "0x" + evm_address(address);
|
return "0x" + evm_address(address);
|
||||||
} else if (isCosmWasmChain(chain)) {
|
} else if (chainToPlatform(chain) === "Cosmwasm") {
|
||||||
return "0x" + toHex(fromBech32(address).data).padStart(64, "0");
|
return "0x" + toHex(fromBech32(address).data).padStart(64, "0");
|
||||||
} else if (chain === "solana" || chain === "pythnet") {
|
} else if (chain === "Solana" || chain === "Pythnet") {
|
||||||
return "0x" + toHex(base58.decode(address)).padStart(64, "0");
|
return "0x" + toHex(base58.decode(address)).padStart(64, "0");
|
||||||
} else if (chain === "algorand") {
|
} else if (chain === "Algorand") {
|
||||||
// TODO: is there a better native format for algorand?
|
// TODO: is there a better native format for algorand?
|
||||||
return "0x" + evm_address(address);
|
return "0x" + evm_address(address);
|
||||||
} else if (chain === "near") {
|
} else if (chain === "Near") {
|
||||||
return "0x" + evm_address(address);
|
return "0x" + evm_address(address);
|
||||||
} else if (chain === "sui") {
|
} else if (chain === "Sui") {
|
||||||
return "0x" + evm_address(address);
|
return "0x" + evm_address(address);
|
||||||
} else if (chain === "aptos") {
|
} else if (chain === "Aptos") {
|
||||||
if (/^(0x)?[0-9a-fA-F]+$/.test(address)) {
|
if (/^(0x)?[0-9a-fA-F]+$/.test(address)) {
|
||||||
return "0x" + evm_address(address);
|
return "0x" + evm_address(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sha3_256(Buffer.from(address)); // address is hash of fully qualified type
|
return sha3_256(Buffer.from(address)); // address is hash of fully qualified type
|
||||||
} else if (chain === "btc") {
|
} else if (chain === "Btc") {
|
||||||
throw Error("btc is not supported yet");
|
throw Error("btc is not supported yet");
|
||||||
} else if (chain === "cosmoshub") {
|
} else if (chain === "Cosmoshub") {
|
||||||
throw Error("cosmoshub is not supported yet");
|
throw Error("cosmoshub is not supported yet");
|
||||||
} else if (chain === "evmos") {
|
} else if (chain === "Evmos") {
|
||||||
throw Error("evmos is not supported yet");
|
throw Error("evmos is not supported yet");
|
||||||
} else if (chain === "kujira") {
|
} else if (chain === "Kujira") {
|
||||||
throw Error("kujira is not supported yet");
|
throw Error("kujira is not supported yet");
|
||||||
} else if (chain === "rootstock") {
|
} else if (chain === "Rootstock") {
|
||||||
throw Error("rootstock is not supported yet");
|
throw Error("rootstock is not supported yet");
|
||||||
} else {
|
} else {
|
||||||
impossible(chain);
|
throw Error(`Unsupported chain: ${chain}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCodeAddress(chain: ChainName, address: string): string {
|
function parseCodeAddress(chain: Chain, address: string): string {
|
||||||
if (isCosmWasmChain(chain)) {
|
if (chainToPlatform(chain) === "Cosmwasm") {
|
||||||
return "0x" + parseInt(address, 10).toString(16).padStart(64, "0");
|
return "0x" + parseInt(address, 10).toString(16).padStart(64, "0");
|
||||||
} else {
|
} else {
|
||||||
return parseAddress(chain, address);
|
return parseAddress(chain, address);
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import {
|
|
||||||
assertChain,
|
|
||||||
coalesceChainId,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { CHAIN_ID_OR_NAME_CHOICES } from "../../consts";
|
import { CHAIN_ID_OR_NAME_CHOICES } from "../../consts";
|
||||||
|
import { assertChain, toChain } from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
export const command = "chain-id <chain>";
|
export const command = "chain-id <chain>";
|
||||||
export const desc =
|
export const desc =
|
||||||
|
@ -16,6 +13,6 @@ export const builder = (y: typeof yargs) => {
|
||||||
} as const);
|
} as const);
|
||||||
};
|
};
|
||||||
export const handler = (argv: Awaited<ReturnType<typeof builder>["argv"]>) => {
|
export const handler = (argv: Awaited<ReturnType<typeof builder>["argv"]>) => {
|
||||||
assertChain(argv.chain);
|
assertChain(toChain(argv.chain));
|
||||||
console.log(coalesceChainId(argv.chain));
|
console.log(toChain(argv.chain));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
import {
|
|
||||||
CHAINS,
|
|
||||||
ChainName,
|
|
||||||
assertChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { relayer } from "@certusone/wormhole-sdk";
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { CONTRACTS } from "../../consts";
|
|
||||||
import { assertNetwork } from "../../utils";
|
|
||||||
import { impossible } from "../../vaa";
|
import { impossible } from "../../vaa";
|
||||||
|
import { contracts } from "@wormhole-foundation/sdk-base";
|
||||||
|
import { chainToChain, getNetwork } from "../../utils";
|
||||||
|
|
||||||
export const command = "contract <network> <chain> <module>";
|
export const command = "contract <network> <chain> <module>";
|
||||||
export const desc = "Print contract address";
|
export const desc = "Print contract address";
|
||||||
|
@ -20,7 +14,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
} as const)
|
} as const)
|
||||||
.positional("chain", {
|
.positional("chain", {
|
||||||
describe: "Chain to query",
|
describe: "Chain to query",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.positional("module", {
|
.positional("module", {
|
||||||
|
@ -31,30 +25,27 @@ export const builder = (y: typeof yargs) =>
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
||||||
) => {
|
) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
const chain = chainToChain(argv.chain);
|
||||||
const chain = argv.chain;
|
|
||||||
assertChain(chain);
|
|
||||||
const module = argv["module"];
|
const module = argv["module"];
|
||||||
|
|
||||||
let addr: string | undefined;
|
let addr: string | undefined;
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "Core":
|
case "Core":
|
||||||
addr = CONTRACTS[network][chain].core;
|
addr = contracts.coreBridge.get(network, chain);
|
||||||
break;
|
break;
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
const addresses = CONTRACTS[network][chain];
|
addr = contracts.nftBridge.get(network, chain);
|
||||||
if (!("nft_bridge" in addresses)) {
|
if (!addr) {
|
||||||
throw new Error(`NFTBridge not deployed on ${chain}`);
|
throw new Error(`NFTBridge not deployed on ${chain}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = addresses.nft_bridge;
|
|
||||||
break;
|
break;
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
addr = CONTRACTS[network][chain].token_bridge;
|
addr = contracts.tokenBridge.get(network, chain);
|
||||||
break;
|
break;
|
||||||
case "WormholeRelayer":
|
case "WormholeRelayer":
|
||||||
addr = relayer.RELAYER_CONTRACTS[network][chain]?.wormholeRelayerAddress;
|
addr = contracts.relayer.get(network, chain);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
impossible(module);
|
impossible(module);
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import {
|
|
||||||
CHAINS,
|
|
||||||
ChainName,
|
|
||||||
assertChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { getEmitterAddress } from "../../emitter";
|
import { getEmitterAddress } from "../../emitter";
|
||||||
|
import { assertChain, chains } from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
export const command = "emitter <chain> <address>";
|
export const command = "emitter <chain> <address>";
|
||||||
export const desc = "Print address in emitter address format";
|
export const desc = "Print address in emitter address format";
|
||||||
|
@ -13,7 +9,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
.positional("chain", {
|
.positional("chain", {
|
||||||
describe: "Chain to query",
|
describe: "Chain to query",
|
||||||
type: "string",
|
type: "string",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
choices: chains,
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.positional("address", {
|
.positional("address", {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { tryUint8ArrayToNative } from "@certusone/wormhole-sdk/lib/esm/utils";
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { getOriginalAsset } from "../../chains/generic";
|
import { getOriginalAsset } from "../../chains/generic";
|
||||||
import { CHAIN_ID_OR_NAME_CHOICES, RPC_OPTIONS } from "../../consts";
|
import { CHAIN_ID_OR_NAME_CHOICES, RPC_OPTIONS } from "../../consts";
|
||||||
import { assertNetwork } from "../../utils";
|
import { getNetwork } from "../../utils";
|
||||||
|
import { tryUint8ArrayToNative } from "../../sdk/array";
|
||||||
|
import { toChain } from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
export const command = "origin <chain> <address>";
|
export const command = "origin <chain> <address>";
|
||||||
export const desc = `Print the origin chain and address of the asset that corresponds to the given chain and address.`;
|
export const desc = `Print the origin chain and address of the asset that corresponds to the given chain and address.`;
|
||||||
|
@ -32,12 +33,11 @@ export const handler = async (
|
||||||
const consoleWarnTemp = console.warn;
|
const consoleWarnTemp = console.warn;
|
||||||
console.warn = () => {};
|
console.warn = () => {};
|
||||||
|
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const res = await getOriginalAsset(argv.chain, network, argv.address);
|
const res = await getOriginalAsset(argv.chain, network, argv.address);
|
||||||
console.log({
|
console.log({
|
||||||
...res,
|
...res,
|
||||||
assetAddress: tryUint8ArrayToNative(res.assetAddress, res.chainId),
|
assetAddress: tryUint8ArrayToNative(res.assetAddress, toChain(res.chainId)),
|
||||||
});
|
});
|
||||||
|
|
||||||
console.warn = consoleWarnTemp;
|
console.warn = consoleWarnTemp;
|
||||||
|
|
|
@ -3,16 +3,17 @@
|
||||||
// is defined in the consts.ts file in the SDK (to verify that all chains // are properly registered.)
|
// is defined in the consts.ts file in the SDK (to verify that all chains // are properly registered.)
|
||||||
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import {
|
|
||||||
assertChain,
|
|
||||||
ChainName,
|
|
||||||
CHAINS,
|
|
||||||
Contracts,
|
|
||||||
CONTRACTS,
|
|
||||||
isEVMChain,
|
|
||||||
isTerraChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { getEmitterAddress } from "../../emitter";
|
import { getEmitterAddress } from "../../emitter";
|
||||||
|
import {
|
||||||
|
Network,
|
||||||
|
assertChain,
|
||||||
|
chainToPlatform,
|
||||||
|
chains,
|
||||||
|
contracts,
|
||||||
|
toChain,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { chainToChain, getNetwork } from "../../utils";
|
||||||
|
import { Chain } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export const command = "registrations <network> <chain> <module>";
|
export const command = "registrations <network> <chain> <module>";
|
||||||
export const desc = "Print chain registrations";
|
export const desc = "Print chain registrations";
|
||||||
|
@ -25,7 +26,7 @@ export const builder = (y: typeof yargs) => {
|
||||||
} as const)
|
} as const)
|
||||||
.positional("chain", {
|
.positional("chain", {
|
||||||
describe: "Chain to query",
|
describe: "Chain to query",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.positional("module", {
|
.positional("module", {
|
||||||
|
@ -45,43 +46,39 @@ export const builder = (y: typeof yargs) => {
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
||||||
) => {
|
) => {
|
||||||
assertChain(argv.chain);
|
const chain = chainToChain(argv.chain);
|
||||||
const chain = argv.chain;
|
const network = getNetwork(argv.network);
|
||||||
const network = argv.network.toUpperCase();
|
|
||||||
if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") {
|
|
||||||
throw Error(`Unknown network: ${network}`);
|
|
||||||
}
|
|
||||||
const module = argv.module;
|
const module = argv.module;
|
||||||
if (module !== "TokenBridge" && module !== "NFTBridge") {
|
if (module !== "TokenBridge" && module !== "NFTBridge") {
|
||||||
throw Error(`Module must be TokenBridge or NFTBridge`);
|
throw Error(`Module must be TokenBridge or NFTBridge`);
|
||||||
}
|
}
|
||||||
let results: object;
|
let results: object;
|
||||||
if (chain === "solana") {
|
if (chain === "Solana") {
|
||||||
const solana = require("../../solana");
|
const solana = require("../../solana");
|
||||||
results = await solana.queryRegistrationsSolana(network, module);
|
results = await solana.queryRegistrationsSolana(network, module);
|
||||||
} else if (isEVMChain(chain)) {
|
} else if (chainToPlatform(chain) === "Evm") {
|
||||||
const evm = require("../../evm");
|
const evm = require("../../evm");
|
||||||
results = await evm.queryRegistrationsEvm(network, chain, module);
|
results = await evm.queryRegistrationsEvm(network, chain, module);
|
||||||
} else if (isTerraChain(chain) || chain === "xpla") {
|
} else if (chain === "Terra" || chain === "Terra2" || chain === "Xpla") {
|
||||||
const terra = require("../../terra");
|
const terra = require("../../terra");
|
||||||
results = await terra.queryRegistrationsTerra(network, chain, module);
|
results = await terra.queryRegistrationsTerra(network, chain, module);
|
||||||
} else if (chain === "injective") {
|
} else if (chain === "Injective") {
|
||||||
const injective = require("../../injective");
|
const injective = require("../../injective");
|
||||||
results = await injective.queryRegistrationsInjective(network, module);
|
results = await injective.queryRegistrationsInjective(network, module);
|
||||||
} else if (chain === "sei") {
|
} else if (chain === "Sei") {
|
||||||
const sei = require("../../chains/sei/registrations");
|
const sei = require("../../chains/sei/registrations");
|
||||||
results = await sei.queryRegistrationsSei(network, module);
|
results = await sei.queryRegistrationsSei(network, module);
|
||||||
} else if (chain === "sui") {
|
} else if (chain === "Sui") {
|
||||||
const sui = require("../../chains/sui/registrations");
|
const sui = require("../../chains/sui/registrations");
|
||||||
results = await sui.queryRegistrationsSui(network, module);
|
results = await sui.queryRegistrationsSui(network, module);
|
||||||
} else if (chain === "aptos") {
|
} else if (chain === "Aptos") {
|
||||||
const aptos = require("../../aptos");
|
const aptos = require("../../aptos");
|
||||||
results = await aptos.queryRegistrationsAptos(network, module);
|
results = await aptos.queryRegistrationsAptos(network, module);
|
||||||
} else {
|
} else {
|
||||||
throw Error(`Command not supported for chain ${chain}`);
|
throw Error(`Command not supported for chain ${chain}`);
|
||||||
}
|
}
|
||||||
if (argv["verify"]) {
|
if (argv["verify"]) {
|
||||||
verifyRegistrations(network, chain as string, module, results);
|
verifyRegistrations(network, chain, module, results);
|
||||||
} else {
|
} else {
|
||||||
console.log(results);
|
console.log(results);
|
||||||
}
|
}
|
||||||
|
@ -89,8 +86,8 @@ export const handler = async (
|
||||||
|
|
||||||
// verifyRegistrations takes the results returned above and verifies them against the expected values in the consts file.
|
// verifyRegistrations takes the results returned above and verifies them against the expected values in the consts file.
|
||||||
async function verifyRegistrations(
|
async function verifyRegistrations(
|
||||||
network: "MAINNET" | "TESTNET" | "DEVNET",
|
network: Network,
|
||||||
chain: string,
|
chain: Chain,
|
||||||
module: "NFTBridge" | "TokenBridge",
|
module: "NFTBridge" | "TokenBridge",
|
||||||
input: Object
|
input: Object
|
||||||
) {
|
) {
|
||||||
|
@ -104,25 +101,21 @@ async function verifyRegistrations(
|
||||||
|
|
||||||
// Loop over the chains and make sure everything is in our input, and the values match.
|
// Loop over the chains and make sure everything is in our input, and the values match.
|
||||||
const results: { [key: string]: string } = {};
|
const results: { [key: string]: string } = {};
|
||||||
for (const chainStr in CHAINS) {
|
for (const chainStr of chains) {
|
||||||
const thisChain = chainStr as ChainName;
|
const thisChain = toChain(chainStr);
|
||||||
if (thisChain === "unset" || thisChain === chain) {
|
if (thisChain === chain) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const contracts: Contracts = CONTRACTS[network][thisChain];
|
|
||||||
|
|
||||||
let expectedAddr: string | undefined;
|
let expectedAddr: string | undefined;
|
||||||
if (module === "TokenBridge") {
|
if (module === "TokenBridge") {
|
||||||
expectedAddr = contracts.token_bridge;
|
expectedAddr = contracts.tokenBridge.get(network, thisChain);
|
||||||
} else {
|
} else {
|
||||||
expectedAddr = contracts.nft_bridge;
|
expectedAddr = contracts.nftBridge.get(network, thisChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedAddr !== undefined) {
|
if (expectedAddr !== undefined) {
|
||||||
expectedAddr = await getEmitterAddress(
|
expectedAddr = await getEmitterAddress(thisChain, expectedAddr);
|
||||||
thisChain as ChainName,
|
|
||||||
expectedAddr
|
|
||||||
);
|
|
||||||
if (!expectedAddr.startsWith("0x")) {
|
if (!expectedAddr.startsWith("0x")) {
|
||||||
expectedAddr = "0x" + expectedAddr;
|
expectedAddr = "0x" + expectedAddr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
import {
|
|
||||||
CHAINS,
|
|
||||||
ChainName,
|
|
||||||
assertChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { NETWORKS } from "../../consts";
|
import { NETWORKS } from "../../consts";
|
||||||
import { assertNetwork } from "../../utils";
|
import { chainToChain, getNetwork } from "../../utils";
|
||||||
|
|
||||||
export const command = "rpc <network> <chain>";
|
export const command = "rpc <network> <chain>";
|
||||||
export const desc = "Print RPC address";
|
export const desc = "Print RPC address";
|
||||||
|
@ -18,14 +13,12 @@ export const builder = (y: typeof yargs) =>
|
||||||
} as const)
|
} as const)
|
||||||
.positional("chain", {
|
.positional("chain", {
|
||||||
describe: "Chain to query",
|
describe: "Chain to query",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const);
|
} as const);
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
||||||
) => {
|
) => {
|
||||||
assertChain(argv.chain);
|
const network = getNetwork(argv.network);
|
||||||
const network = argv.network.toUpperCase();
|
console.log(NETWORKS[network][chainToChain(argv.chain)].rpc);
|
||||||
assertNetwork(network);
|
|
||||||
console.log(NETWORKS[network][argv.chain].rpc);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { assertChain } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
import { assertChain } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { getWrappedAssetAddress } from "../../chains/generic/getWrappedAssetAddress";
|
import { getWrappedAssetAddress } from "../../chains/generic/getWrappedAssetAddress";
|
||||||
import { CHAIN_ID_OR_NAME_CHOICES, RPC_OPTIONS } from "../../consts";
|
import { RPC_OPTIONS } from "../../consts";
|
||||||
import { assertNetwork } from "../../utils";
|
import { chainToChain, getNetwork } from "../../utils";
|
||||||
|
|
||||||
export const command = "wrapped <origin-chain> <origin-address> <target-chain>";
|
export const command = "wrapped <origin-chain> <origin-address> <target-chain>";
|
||||||
export const desc =
|
export const desc =
|
||||||
|
@ -11,7 +11,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
y
|
y
|
||||||
.positional("origin-chain", {
|
.positional("origin-chain", {
|
||||||
describe: "Chain that wrapped asset came from",
|
describe: "Chain that wrapped asset came from",
|
||||||
choices: CHAIN_ID_OR_NAME_CHOICES,
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.positional("origin-address", {
|
.positional("origin-address", {
|
||||||
|
@ -21,7 +21,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
})
|
})
|
||||||
.positional("target-chain", {
|
.positional("target-chain", {
|
||||||
describe: "Chain to query for wrapped asset address",
|
describe: "Chain to query for wrapped asset address",
|
||||||
choices: CHAIN_ID_OR_NAME_CHOICES,
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.option("network", {
|
.option("network", {
|
||||||
|
@ -42,14 +42,13 @@ export const handler = async (
|
||||||
const consoleWarnTemp = console.warn;
|
const consoleWarnTemp = console.warn;
|
||||||
console.warn = () => {};
|
console.warn = () => {};
|
||||||
|
|
||||||
const originChain = argv["origin-chain"];
|
const originChain = chainToChain(argv["origin-chain"]);
|
||||||
const originAddress = argv["origin-address"];
|
const originAddress = argv["origin-address"];
|
||||||
const targetChain = argv["target-chain"];
|
const targetChain = chainToChain(argv["target-chain"]);
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
|
|
||||||
assertChain(originChain);
|
assertChain(originChain);
|
||||||
assertChain(targetChain);
|
assertChain(targetChain);
|
||||||
assertNetwork(network);
|
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
await getWrappedAssetAddress(
|
await getWrappedAssetAddress(
|
||||||
|
|
|
@ -4,8 +4,9 @@ import { Account, KeyPair, connect } from "near-api-js";
|
||||||
import { InMemoryKeyStore } from "near-api-js/lib/key_stores";
|
import { InMemoryKeyStore } from "near-api-js/lib/key_stores";
|
||||||
import { parseSeedPhrase } from "near-seed-phrase";
|
import { parseSeedPhrase } from "near-seed-phrase";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { CONTRACTS, NETWORKS, NETWORK_OPTIONS, RPC_OPTIONS } from "../consts";
|
import { NETWORKS, NETWORK_OPTIONS, RPC_OPTIONS } from "../consts";
|
||||||
import { assertNetwork } from "../utils";
|
import { contracts } from "@wormhole-foundation/sdk-base";
|
||||||
|
import { getNetwork } from "../utils";
|
||||||
|
|
||||||
// Near utilities
|
// Near utilities
|
||||||
export const command = "near";
|
export const command = "near";
|
||||||
|
@ -55,14 +56,12 @@ export const builder = function (y: typeof yargs) {
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
}),
|
}),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const contracts = CONTRACTS[network].near;
|
|
||||||
const {
|
const {
|
||||||
rpc: defaultRpc,
|
rpc: defaultRpc,
|
||||||
key: defaultKey,
|
key: defaultKey,
|
||||||
networkId,
|
networkId,
|
||||||
} = NETWORKS[network].near;
|
} = NETWORKS[network].Near;
|
||||||
|
|
||||||
const key =
|
const key =
|
||||||
argv.key ??
|
argv.key ??
|
||||||
|
@ -80,12 +79,12 @@ export const builder = function (y: typeof yargs) {
|
||||||
let target = argv.target;
|
let target = argv.target;
|
||||||
if (!argv.target && argv.module) {
|
if (!argv.target && argv.module) {
|
||||||
if (argv.module === "Core") {
|
if (argv.module === "Core") {
|
||||||
target = contracts.core;
|
target = contracts.coreBridge(network, "Near");
|
||||||
console.log("Setting target to core");
|
console.log("Setting target to core");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv.module === "TokenBridge") {
|
if (argv.module === "TokenBridge") {
|
||||||
target = contracts.token_bridge;
|
target = contracts.tokenBridge(network, "Near");
|
||||||
console.log("Setting target to token_bridge");
|
console.log("Setting target to token_bridge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,14 +124,12 @@ export const builder = function (y: typeof yargs) {
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
}),
|
}),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const contracts = CONTRACTS[network].near;
|
|
||||||
const {
|
const {
|
||||||
rpc: defaultRpc,
|
rpc: defaultRpc,
|
||||||
key: defaultKey,
|
key: defaultKey,
|
||||||
networkId,
|
networkId,
|
||||||
} = NETWORKS[network].near;
|
} = NETWORKS[network].Near;
|
||||||
|
|
||||||
const key =
|
const key =
|
||||||
argv.key ??
|
argv.key ??
|
||||||
|
@ -150,12 +147,12 @@ export const builder = function (y: typeof yargs) {
|
||||||
let target = argv.target;
|
let target = argv.target;
|
||||||
if (!argv.target && argv.module) {
|
if (!argv.target && argv.module) {
|
||||||
if (argv.module === "Core") {
|
if (argv.module === "Core") {
|
||||||
target = contracts.core;
|
target = contracts.coreBridge(network, "Near");
|
||||||
console.log("Setting target to core");
|
console.log("Setting target to core");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv.module === "TokenBridge") {
|
if (argv.module === "TokenBridge") {
|
||||||
target = contracts.token_bridge;
|
target = contracts.tokenBridge(network, "Near");
|
||||||
console.log("Setting target to token_bridge");
|
console.log("Setting target to token_bridge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
import {
|
import yargs from "yargs";
|
||||||
CHAINS,
|
|
||||||
ChainName,
|
|
||||||
assertChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { relayer, Network } from "@certusone/wormhole-sdk";
|
|
||||||
import yargs, { string } from "yargs";
|
|
||||||
import { CONTRACTS, NETWORKS } from "../consts";
|
|
||||||
import { assertNetwork } from "../utils";
|
|
||||||
import { impossible } from "../vaa";
|
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
|
import { NETWORKS } from "../consts";
|
||||||
|
import { chainToChain, getNetwork } from "../utils";
|
||||||
|
import { Chain, assertChain, contracts } from "@wormhole-foundation/sdk-base";
|
||||||
|
import { relayer } from "@certusone/wormhole-sdk";
|
||||||
|
|
||||||
export const command = "status <network> <chain> <tx>";
|
export const command = "status <network> <chain> <tx>";
|
||||||
export const desc =
|
export const desc =
|
||||||
|
@ -22,7 +17,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
} as const)
|
} as const)
|
||||||
.positional("chain", {
|
.positional("chain", {
|
||||||
describe: "Source chain",
|
describe: "Source chain",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const)
|
||||||
.positional("tx", {
|
.positional("tx", {
|
||||||
|
@ -33,34 +28,32 @@ export const builder = (y: typeof yargs) =>
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
||||||
) => {
|
) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
const chain = chainToChain(argv.chain);
|
||||||
const chain = argv.chain;
|
|
||||||
assertChain(chain);
|
assertChain(chain);
|
||||||
|
|
||||||
const addr =
|
const addr = contracts.relayer.get(network, chain);
|
||||||
relayer.RELAYER_CONTRACTS[network][chain]?.wormholeRelayerAddress;
|
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
throw new Error(`Wormhole Relayer not deployed on ${chain} in ${network}`);
|
throw new Error(`Wormhole Relayer not deployed on ${chain} in ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sourceRPC = NETWORKS[network as Network][chain as ChainName].rpc;
|
const sourceRPC = NETWORKS[network][chain].rpc;
|
||||||
const sourceChainProvider = new ethers.providers.JsonRpcProvider(sourceRPC);
|
const sourceChainProvider = new ethers.providers.JsonRpcProvider(sourceRPC);
|
||||||
const targetChainProviders = new Map<ChainName, ethers.providers.Provider>();
|
const targetChainProviders = new Map<Chain, ethers.providers.Provider>();
|
||||||
for (const key in NETWORKS[network]) {
|
for (const key in NETWORKS[network]) {
|
||||||
targetChainProviders.set(
|
targetChainProviders.set(
|
||||||
key as ChainName,
|
key as Chain,
|
||||||
new ethers.providers.JsonRpcProvider(
|
new ethers.providers.JsonRpcProvider(NETWORKS[network][key as Chain].rpc)
|
||||||
NETWORKS[network as Network][key as ChainName].rpc
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const info = await relayer.getWormholeRelayerInfo(chain, argv.tx, {
|
// TODO: Convert this over to sdkv2
|
||||||
environment: network,
|
// const info = await relayer.getWormholeRelayerInfo(chain, argv.tx, {
|
||||||
sourceChainProvider,
|
// environment: network,
|
||||||
targetChainProviders,
|
// sourceChainProvider,
|
||||||
});
|
// targetChainProviders,
|
||||||
|
// });
|
||||||
|
// console.log(relayer.stringifyWormholeRelayerInfo(info));
|
||||||
|
|
||||||
console.log(relayer.stringifyWormholeRelayerInfo(info));
|
console.log("Not implemented");
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +1,3 @@
|
||||||
import {
|
|
||||||
assertChain,
|
|
||||||
ChainId,
|
|
||||||
ChainName,
|
|
||||||
CHAINS,
|
|
||||||
coalesceChainName,
|
|
||||||
Contracts,
|
|
||||||
CONTRACTS,
|
|
||||||
isEVMChain,
|
|
||||||
isTerraChain,
|
|
||||||
toChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { execute_algorand } from "../algorand";
|
import { execute_algorand } from "../algorand";
|
||||||
import { execute_aptos } from "../aptos";
|
import { execute_aptos } from "../aptos";
|
||||||
|
@ -21,11 +9,22 @@ import { execute_injective } from "../injective";
|
||||||
import { execute_near } from "../near";
|
import { execute_near } from "../near";
|
||||||
import { execute_solana } from "../solana";
|
import { execute_solana } from "../solana";
|
||||||
import { execute_terra } from "../terra";
|
import { execute_terra } from "../terra";
|
||||||
import { assertNetwork } from "../utils";
|
|
||||||
import { assertKnownPayload, impossible, parse, Payload, VAA } from "../vaa";
|
import { assertKnownPayload, impossible, parse, Payload, VAA } from "../vaa";
|
||||||
import { execute_xpla } from "../xpla";
|
import { execute_xpla } from "../xpla";
|
||||||
import { NETWORKS } from "../consts";
|
import { NETWORKS } from "../consts";
|
||||||
import { Network } from "../utils";
|
import { chainToChain, getNetwork } from "../utils";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
Network,
|
||||||
|
PlatformToChains,
|
||||||
|
assertChain,
|
||||||
|
assertChainId,
|
||||||
|
chainIdToChain,
|
||||||
|
chainToPlatform,
|
||||||
|
chains,
|
||||||
|
contracts,
|
||||||
|
toChain,
|
||||||
|
} from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export const command = "submit <vaa>";
|
export const command = "submit <vaa>";
|
||||||
export const desc = "Execute a VAA";
|
export const desc = "Execute a VAA";
|
||||||
|
@ -39,7 +38,7 @@ export const builder = (y: typeof yargs) =>
|
||||||
.option("chain", {
|
.option("chain", {
|
||||||
alias: "c",
|
alias: "c",
|
||||||
describe: "chain name",
|
describe: "chain name",
|
||||||
choices: Object.keys(CHAINS) as ChainName[],
|
type: "string",
|
||||||
demandOption: false,
|
demandOption: false,
|
||||||
} as const)
|
} as const)
|
||||||
.option("network", NETWORK_OPTIONS)
|
.option("network", NETWORK_OPTIONS)
|
||||||
|
@ -72,8 +71,7 @@ export const handler = async (
|
||||||
assertKnownPayload(parsed_vaa);
|
assertKnownPayload(parsed_vaa);
|
||||||
console.log(parsed_vaa.payload);
|
console.log(parsed_vaa.payload);
|
||||||
|
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
|
|
||||||
if (argv["all-chains"]) {
|
if (argv["all-chains"]) {
|
||||||
if (argv.rpc) {
|
if (argv.rpc) {
|
||||||
|
@ -104,22 +102,34 @@ export const handler = async (
|
||||||
// get VAA chain
|
// get VAA chain
|
||||||
const vaa_chain_id =
|
const vaa_chain_id =
|
||||||
"chain" in parsed_vaa.payload ? parsed_vaa.payload.chain : 0;
|
"chain" in parsed_vaa.payload ? parsed_vaa.payload.chain : 0;
|
||||||
assertChain(vaa_chain_id);
|
|
||||||
const vaa_chain = toChainName(vaa_chain_id);
|
// if vaa_chain_id is 0, it means the chain is not specified in the VAA.
|
||||||
|
// We don't have a notion of an unsupported chain, so we don't want to just assert.
|
||||||
|
let vaa_chain;
|
||||||
|
if (vaa_chain_id !== 0) {
|
||||||
|
assertChainId(vaa_chain_id);
|
||||||
|
vaa_chain = chainIdToChain(vaa_chain_id);
|
||||||
|
}
|
||||||
|
|
||||||
// get chain from command line arg
|
// get chain from command line arg
|
||||||
const cli_chain = argv.chain;
|
const cli_chain = argv.chain ? chainToChain(argv.chain) : argv.chain;
|
||||||
|
|
||||||
let chain: ChainName;
|
let chain: Chain;
|
||||||
if (cli_chain !== undefined) {
|
if (cli_chain !== undefined) {
|
||||||
assertChain(cli_chain);
|
assertChain(cli_chain);
|
||||||
if (vaa_chain !== "unset" && cli_chain !== vaa_chain) {
|
if (vaa_chain && cli_chain !== vaa_chain) {
|
||||||
throw Error(
|
throw Error(
|
||||||
`Specified target chain (${cli_chain}) does not match VAA target chain (${vaa_chain})`
|
`Specified target chain (${cli_chain}) does not match VAA target chain (${vaa_chain})`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
chain = coalesceChainName(cli_chain);
|
chain = toChain(cli_chain);
|
||||||
} else {
|
} else {
|
||||||
|
if (!vaa_chain) {
|
||||||
|
throw Error(
|
||||||
|
`VAA does not specify a target chain and one was not provided, please specify one with --chain or -c`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assertChain(vaa_chain);
|
||||||
chain = vaa_chain;
|
chain = vaa_chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,75 +149,59 @@ async function executeSubmit(
|
||||||
parsedVaa: VAA<Payload>,
|
parsedVaa: VAA<Payload>,
|
||||||
buf: Buffer,
|
buf: Buffer,
|
||||||
network: Network,
|
network: Network,
|
||||||
chain: ChainName,
|
chain: Chain,
|
||||||
rpc: string | undefined,
|
rpc: string | undefined,
|
||||||
contractAddress: string | undefined
|
contractAddress: string | undefined
|
||||||
) {
|
) {
|
||||||
if (chain === "unset") {
|
if (chainToPlatform(chain) === "Evm") {
|
||||||
throw Error(
|
|
||||||
"This VAA does not specify the target chain, please provide it by hand using the '--chain' flag."
|
|
||||||
);
|
|
||||||
} else if (isEVMChain(chain)) {
|
|
||||||
await execute_evm(
|
await execute_evm(
|
||||||
parsedVaa.payload,
|
parsedVaa.payload,
|
||||||
buf,
|
buf,
|
||||||
network,
|
network,
|
||||||
chain,
|
chain as PlatformToChains<"Evm">,
|
||||||
contractAddress,
|
contractAddress,
|
||||||
rpc
|
rpc
|
||||||
);
|
);
|
||||||
} else if (isTerraChain(chain)) {
|
} else if (chain === "Terra" || chain === "Terra2") {
|
||||||
await execute_terra(parsedVaa.payload, buf, network, chain);
|
await execute_terra(parsedVaa.payload, buf, network, chain);
|
||||||
} else if (chain === "solana" || chain === "pythnet") {
|
} else if (chain === "Solana" || chain === "Pythnet") {
|
||||||
await execute_solana(parsedVaa, buf, network, chain);
|
await execute_solana(parsedVaa, buf, network, chain);
|
||||||
} else if (chain === "algorand") {
|
} else if (chain === "Algorand") {
|
||||||
await execute_algorand(
|
await execute_algorand(
|
||||||
parsedVaa.payload,
|
parsedVaa.payload,
|
||||||
new Uint8Array(Buffer.from(vaaHex, "hex")),
|
new Uint8Array(Buffer.from(vaaHex, "hex")),
|
||||||
network
|
network
|
||||||
);
|
);
|
||||||
} else if (chain === "near") {
|
} else if (chain === "Near") {
|
||||||
await execute_near(parsedVaa.payload, vaaHex, network);
|
await execute_near(parsedVaa.payload, vaaHex, network);
|
||||||
} else if (chain === "injective") {
|
} else if (chain === "Injective") {
|
||||||
await execute_injective(parsedVaa.payload, buf, network);
|
await execute_injective(parsedVaa.payload, buf, network);
|
||||||
} else if (chain === "xpla") {
|
} else if (chain === "Xpla") {
|
||||||
await execute_xpla(parsedVaa.payload, buf, network);
|
await execute_xpla(parsedVaa.payload, buf, network);
|
||||||
} else if (chain === "sei") {
|
} else if (chain === "Sei") {
|
||||||
await submitSei(parsedVaa.payload, buf, network, rpc);
|
await submitSei(parsedVaa.payload, buf, network, rpc);
|
||||||
} else if (chain === "osmosis") {
|
} else if (chain === "Osmosis") {
|
||||||
throw Error("OSMOSIS is not supported yet");
|
throw Error("OSMOSIS is not supported yet");
|
||||||
} else if (chain === "sui") {
|
} else if (chain === "Sui") {
|
||||||
await submitSui(parsedVaa.payload, buf, network, rpc);
|
await submitSui(parsedVaa.payload, buf, network, rpc);
|
||||||
} else if (chain === "aptos") {
|
} else if (chain === "Aptos") {
|
||||||
await execute_aptos(parsedVaa.payload, buf, network, contractAddress, rpc);
|
await execute_aptos(parsedVaa.payload, buf, network, contractAddress, rpc);
|
||||||
} else if (chain === "wormchain") {
|
} else if (chain === "Wormchain") {
|
||||||
throw Error("Wormchain is not supported yet");
|
throw Error("Wormchain is not supported yet");
|
||||||
} else if (chain === "btc") {
|
} else if (chain === "Btc") {
|
||||||
throw Error("btc is not supported yet");
|
throw Error("btc is not supported yet");
|
||||||
} else if (chain === "cosmoshub") {
|
} else if (chain === "Cosmoshub") {
|
||||||
throw Error("Cosmoshub is not supported yet");
|
throw Error("Cosmoshub is not supported yet");
|
||||||
} else if (chain === "evmos") {
|
} else if (chain === "Evmos") {
|
||||||
throw Error("Evmos is not supported yet");
|
throw Error("Evmos is not supported yet");
|
||||||
} else if (chain === "kujira") {
|
} else if (chain === "Kujira") {
|
||||||
throw Error("kujira is not supported yet");
|
throw Error("kujira is not supported yet");
|
||||||
} else if (chain === "neutron") {
|
} else if (chain === "Neutron") {
|
||||||
throw Error("neutron is not supported yet");
|
throw Error("neutron is not supported yet");
|
||||||
} else if (chain === "celestia") {
|
} else if (chain === "Celestia") {
|
||||||
throw Error("celestia is not supported yet");
|
throw Error("celestia is not supported yet");
|
||||||
} else if (chain === "stargaze") {
|
|
||||||
throw Error("stargaze is not supported yet");
|
|
||||||
} else if (chain === "seda") {
|
|
||||||
throw Error("seda is not supported yet");
|
|
||||||
} else if (chain === "dymension") {
|
|
||||||
throw Error("dymension is not supported yet");
|
|
||||||
} else if (chain === "provenance") {
|
|
||||||
throw Error("provenance is not supported yet");
|
|
||||||
} else if (chain === "rootstock") {
|
|
||||||
throw Error("rootstock is not supported yet");
|
|
||||||
} else {
|
} else {
|
||||||
// If you get a type error here, hover over `chain`'s type and it tells you
|
throw new Error(`Unsupported chain: ${chain}`);
|
||||||
// which cases are not handled
|
|
||||||
impossible(chain);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,24 +211,19 @@ async function submitToAll(
|
||||||
buf: Buffer,
|
buf: Buffer,
|
||||||
network: Network
|
network: Network
|
||||||
) {
|
) {
|
||||||
let skip_chain: ChainName = "unset";
|
let skip_chain: Chain;
|
||||||
if (parsedVaa.payload.type === "RegisterChain") {
|
if (parsedVaa.payload.type === "RegisterChain") {
|
||||||
skip_chain = toChainName(parsedVaa.payload.emitterChain as ChainId);
|
skip_chain = toChain(parsedVaa.payload.emitterChain);
|
||||||
} else if (parsedVaa.payload.type === "AttestMeta") {
|
} else if (parsedVaa.payload.type === "AttestMeta") {
|
||||||
skip_chain = toChainName(parsedVaa.payload.tokenChain as ChainId);
|
skip_chain = toChain(parsedVaa.payload.tokenChain);
|
||||||
} else {
|
} else {
|
||||||
throw Error(
|
throw Error(
|
||||||
`Invalid VAA payload type (${parsedVaa.payload.type}), only "RegisterChain" and "AttestMeta" are supported with --all-chains`
|
`Invalid VAA payload type (${parsedVaa.payload.type}), only "RegisterChain" and "AttestMeta" are supported with --all-chains`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const chainStr in CHAINS) {
|
for (const chain of chains) {
|
||||||
let chain = chainStr as ChainName;
|
|
||||||
if (chain === "unset") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const n = NETWORKS[network][chain];
|
const n = NETWORKS[network][chain];
|
||||||
const contracts: Contracts = CONTRACTS[network][chain];
|
|
||||||
if (chain == skip_chain) {
|
if (chain == skip_chain) {
|
||||||
console.log(`Skipping ${chain} because it's the origin chain`);
|
console.log(`Skipping ${chain} because it's the origin chain`);
|
||||||
continue;
|
continue;
|
||||||
|
@ -243,15 +232,11 @@ async function submitToAll(
|
||||||
console.log(`Skipping ${chain} because the rpc is not defined`);
|
console.log(`Skipping ${chain} because the rpc is not defined`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!contracts) {
|
|
||||||
console.log(
|
|
||||||
`Skipping ${chain} because the contract entry is not defined`
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
(parsedVaa.payload.module === "TokenBridge" && !contracts.token_bridge) ||
|
(parsedVaa.payload.module === "TokenBridge" &&
|
||||||
(parsedVaa.payload.module === "NFTBridge" && !contracts.nft_bridge)
|
!contracts.tokenBridge.get(network, chain)) ||
|
||||||
|
(parsedVaa.payload.module === "NFTBridge" &&
|
||||||
|
!contracts.nftBridge.get(network, chain))
|
||||||
) {
|
) {
|
||||||
console.log(`Skipping ${chain} because the contract is not defined`);
|
console.log(`Skipping ${chain} because the contract is not defined`);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { buildCoin, getProvider } from "../../chains/sui";
|
import { buildCoin, getProvider } from "../../chains/sui";
|
||||||
import {
|
import { NETWORKS, NETWORK_OPTIONS, RPC_OPTIONS } from "../../consts";
|
||||||
CONTRACTS,
|
import { checkBinary, getNetwork } from "../../utils";
|
||||||
NETWORKS,
|
|
||||||
NETWORK_OPTIONS,
|
|
||||||
RPC_OPTIONS,
|
|
||||||
} from "../../consts";
|
|
||||||
import { assertNetwork, checkBinary } from "../../utils";
|
|
||||||
import { YargsAddCommandsFn } from "../Yargs";
|
import { YargsAddCommandsFn } from "../Yargs";
|
||||||
|
import { contracts } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
const README_URL =
|
const README_URL =
|
||||||
"https://github.com/wormhole-foundation/wormhole/blob/main/sui/README.md";
|
"https://github.com/wormhole-foundation/wormhole/blob/main/sui/README.md";
|
||||||
|
@ -58,17 +54,16 @@ export const addBuildCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
checkBinary("sui", README_URL);
|
checkBinary("sui", README_URL);
|
||||||
|
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const decimals = argv["decimals"];
|
const decimals = argv["decimals"];
|
||||||
const version = argv["version-struct"];
|
const version = argv["version-struct"];
|
||||||
const packagePath =
|
const packagePath =
|
||||||
argv["package-path"] ??
|
argv["package-path"] ??
|
||||||
path.resolve(__dirname, "../../../../../sui/examples");
|
path.resolve(__dirname, "../../../../../sui/examples");
|
||||||
const coreBridgeStateObjectId =
|
const coreBridgeStateObjectId =
|
||||||
argv["wormhole-state"] ?? CONTRACTS[network].sui.core;
|
argv["wormhole-state"] ?? contracts.coreBridge(network, "Sui");
|
||||||
const tokenBridgeStateObjectId =
|
const tokenBridgeStateObjectId =
|
||||||
argv["token-bridge-state"] ?? CONTRACTS[network].sui.token_bridge;
|
argv["token-bridge-state"] ?? contracts.tokenBridge(network, "Sui");
|
||||||
|
|
||||||
if (!coreBridgeStateObjectId) {
|
if (!coreBridgeStateObjectId) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -84,7 +79,7 @@ export const addBuildCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
|
|
||||||
const provider = getProvider(
|
const provider = getProvider(
|
||||||
network,
|
network,
|
||||||
argv.rpc ?? NETWORKS[network].sui.rpc
|
argv.rpc ?? NETWORKS[network].Sui.rpc
|
||||||
);
|
);
|
||||||
const build = await buildCoin(
|
const build = await buildCoin(
|
||||||
provider,
|
provider,
|
||||||
|
|
|
@ -17,8 +17,9 @@ import {
|
||||||
PRIVATE_KEY_OPTIONS,
|
PRIVATE_KEY_OPTIONS,
|
||||||
RPC_OPTIONS,
|
RPC_OPTIONS,
|
||||||
} from "../../consts";
|
} from "../../consts";
|
||||||
import { Network, assertNetwork, checkBinary } from "../../utils";
|
import { checkBinary, getNetwork } from "../../utils";
|
||||||
import { YargsAddCommandsFn } from "../Yargs";
|
import { YargsAddCommandsFn } from "../Yargs";
|
||||||
|
import { Network } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
const README_URL =
|
const README_URL =
|
||||||
"https://github.com/wormhole-foundation/wormhole/blob/main/sui/README.md";
|
"https://github.com/wormhole-foundation/wormhole/blob/main/sui/README.md";
|
||||||
|
@ -42,8 +43,7 @@ export const addDeployCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
checkBinary("sui", README_URL);
|
checkBinary("sui", README_URL);
|
||||||
|
|
||||||
const packageDir = argv["package-dir"];
|
const packageDir = argv["package-dir"];
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const debug = argv.debug ?? false;
|
const debug = argv.debug ?? false;
|
||||||
const privateKey = argv["private-key"];
|
const privateKey = argv["private-key"];
|
||||||
const rpc = argv.rpc;
|
const rpc = argv.rpc;
|
||||||
|
@ -66,7 +66,7 @@ export const deploy = async (
|
||||||
rpc?: string,
|
rpc?: string,
|
||||||
privateKey?: string
|
privateKey?: string
|
||||||
): Promise<SuiTransactionBlockResponse> => {
|
): Promise<SuiTransactionBlockResponse> => {
|
||||||
rpc = rpc ?? NETWORKS[network].sui.rpc;
|
rpc = rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
const signer = getSigner(provider, network, privateKey);
|
const signer = getSigner(provider, network, privateKey);
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,9 @@ import {
|
||||||
PRIVATE_KEY_OPTIONS,
|
PRIVATE_KEY_OPTIONS,
|
||||||
RPC_OPTIONS,
|
RPC_OPTIONS,
|
||||||
} from "../../consts";
|
} from "../../consts";
|
||||||
import { Network, assertNetwork } from "../../utils";
|
|
||||||
import { YargsAddCommandsFn } from "../Yargs";
|
import { YargsAddCommandsFn } from "../Yargs";
|
||||||
|
import { getNetwork } from "../../utils";
|
||||||
|
import { Network } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export const addInitCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
export const addInitCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
y
|
y
|
||||||
|
@ -48,8 +49,7 @@ export const addInitCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
.option("private-key", PRIVATE_KEY_OPTIONS)
|
.option("private-key", PRIVATE_KEY_OPTIONS)
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const packageId = argv["package-id"];
|
const packageId = argv["package-id"];
|
||||||
const wormholeStateObjectId = argv["wormhole-state"];
|
const wormholeStateObjectId = argv["wormhole-state"];
|
||||||
const privateKey = argv["private-key"];
|
const privateKey = argv["private-key"];
|
||||||
|
@ -108,14 +108,13 @@ export const addInitCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
.option("private-key", PRIVATE_KEY_OPTIONS)
|
.option("private-key", PRIVATE_KEY_OPTIONS)
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const packageId = argv["package-id"];
|
const packageId = argv["package-id"];
|
||||||
const wormholeStateObjectId = argv["wormhole-state"];
|
const wormholeStateObjectId = argv["wormhole-state"];
|
||||||
const governanceChainId = argv["governance-chain-id"];
|
const governanceChainId = argv["governance-chain-id"];
|
||||||
const governanceContract = argv["governance-address"];
|
const governanceContract = argv["governance-address"];
|
||||||
const privateKey = argv["private-key"];
|
const privateKey = argv["private-key"];
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].sui.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
|
|
||||||
const res = await initTokenBridge(
|
const res = await initTokenBridge(
|
||||||
network,
|
network,
|
||||||
|
@ -180,8 +179,7 @@ export const addInitCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
.option("private-key", PRIVATE_KEY_OPTIONS)
|
.option("private-key", PRIVATE_KEY_OPTIONS)
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const packageId = argv["package-id"];
|
const packageId = argv["package-id"];
|
||||||
const initialGuardian = argv["initial-guardian"];
|
const initialGuardian = argv["initial-guardian"];
|
||||||
const debug = argv.debug ?? false;
|
const debug = argv.debug ?? false;
|
||||||
|
@ -222,7 +220,7 @@ export const initExampleApp = async (
|
||||||
rpc?: string,
|
rpc?: string,
|
||||||
privateKey?: string
|
privateKey?: string
|
||||||
): Promise<SuiTransactionBlockResponse> => {
|
): Promise<SuiTransactionBlockResponse> => {
|
||||||
rpc = rpc ?? NETWORKS[network].sui.rpc;
|
rpc = rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
const signer = getSigner(provider, network, privateKey);
|
const signer = getSigner(provider, network, privateKey);
|
||||||
|
|
||||||
|
@ -244,7 +242,7 @@ export const initTokenBridge = async (
|
||||||
rpc?: string,
|
rpc?: string,
|
||||||
privateKey?: string
|
privateKey?: string
|
||||||
): Promise<SuiTransactionBlockResponse> => {
|
): Promise<SuiTransactionBlockResponse> => {
|
||||||
rpc = rpc ?? NETWORKS[network].sui.rpc;
|
rpc = rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
const signer = getSigner(provider, network, privateKey);
|
const signer = getSigner(provider, network, privateKey);
|
||||||
const owner = await signer.getAddress();
|
const owner = await signer.getAddress();
|
||||||
|
@ -307,7 +305,7 @@ export const initWormhole = async (
|
||||||
rpc?: string,
|
rpc?: string,
|
||||||
privateKey?: string
|
privateKey?: string
|
||||||
): Promise<SuiTransactionBlockResponse> => {
|
): Promise<SuiTransactionBlockResponse> => {
|
||||||
rpc = rpc ?? NETWORKS[network].sui.rpc;
|
rpc = rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
const signer = getSigner(provider, network, privateKey);
|
const signer = getSigner(provider, network, privateKey);
|
||||||
const owner = await signer.getAddress();
|
const owner = await signer.getAddress();
|
||||||
|
|
|
@ -13,8 +13,8 @@ import {
|
||||||
setMaxGasBudgetDevnet,
|
setMaxGasBudgetDevnet,
|
||||||
} from "../../chains/sui";
|
} from "../../chains/sui";
|
||||||
import { NETWORK_OPTIONS, NETWORKS, RPC_OPTIONS } from "../../consts";
|
import { NETWORK_OPTIONS, NETWORKS, RPC_OPTIONS } from "../../consts";
|
||||||
import { assertNetwork } from "../../utils";
|
|
||||||
import { YargsAddCommandsFn } from "../Yargs";
|
import { YargsAddCommandsFn } from "../Yargs";
|
||||||
|
import { getNetwork } from "../../utils";
|
||||||
|
|
||||||
export const addPublishMessageCommands: YargsAddCommandsFn = (
|
export const addPublishMessageCommands: YargsAddCommandsFn = (
|
||||||
y: typeof yargs
|
y: typeof yargs
|
||||||
|
@ -57,14 +57,13 @@ export const addPublishMessageCommands: YargsAddCommandsFn = (
|
||||||
})
|
})
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
const packageId = argv["package-id"];
|
const packageId = argv["package-id"];
|
||||||
const stateObjectId = argv.state;
|
const stateObjectId = argv.state;
|
||||||
const wormholeStateObjectId = argv["wormhole-state"];
|
const wormholeStateObjectId = argv["wormhole-state"];
|
||||||
const message = argv.message;
|
const message = argv.message;
|
||||||
const privateKey = argv["private-key"];
|
const privateKey = argv["private-key"];
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].sui.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
|
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
const signer = getSigner(provider, network, privateKey);
|
const signer = getSigner(provider, network, privateKey);
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
import {
|
|
||||||
ChainId,
|
|
||||||
ChainName,
|
|
||||||
coalesceChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { parseTokenBridgeRegisterChainVaa } from "@certusone/wormhole-sdk/lib/esm/vaa/tokenBridge";
|
import { parseTokenBridgeRegisterChainVaa } from "@certusone/wormhole-sdk/lib/esm/vaa/tokenBridge";
|
||||||
import {
|
import {
|
||||||
JsonRpcProvider,
|
JsonRpcProvider,
|
||||||
|
@ -36,6 +31,7 @@ import {
|
||||||
import { YargsAddCommandsFn } from "../Yargs";
|
import { YargsAddCommandsFn } from "../Yargs";
|
||||||
import { deploy } from "./deploy";
|
import { deploy } from "./deploy";
|
||||||
import { initExampleApp, initTokenBridge, initWormhole } from "./init";
|
import { initExampleApp, initTokenBridge, initWormhole } from "./init";
|
||||||
|
import { Chain, chainIdToChain, toChainId } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export const addSetupCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
export const addSetupCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
y.command(
|
y.command(
|
||||||
|
@ -51,9 +47,9 @@ export const addSetupCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
})
|
})
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = "DEVNET";
|
const network = "Devnet";
|
||||||
const privateKey = argv["private-key"];
|
const privateKey = argv["private-key"];
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].sui.rpc;
|
const rpc = argv.rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
|
|
||||||
// Deploy core bridge
|
// Deploy core bridge
|
||||||
console.log("[1/4] Deploying core bridge...");
|
console.log("[1/4] Deploying core bridge...");
|
||||||
|
@ -200,15 +196,15 @@ export const addSetupCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
dotenv.config({ path: envPath });
|
dotenv.config({ path: envPath });
|
||||||
|
|
||||||
const tx = new TransactionBlock();
|
const tx = new TransactionBlock();
|
||||||
setMaxGasBudgetDevnet("DEVNET", tx);
|
setMaxGasBudgetDevnet("Devnet", tx);
|
||||||
const registrations: { chain: ChainName; module: string }[] = [];
|
const registrations: { chain: Chain; module: string }[] = [];
|
||||||
for (const key in process.env) {
|
for (const key in process.env) {
|
||||||
if (/^REGISTER_(.+)_TOKEN_BRIDGE_VAA$/.test(key)) {
|
if (/^REGISTER_(.+)_TOKEN_BRIDGE_VAA$/.test(key)) {
|
||||||
// Get VAA info
|
// Get VAA info
|
||||||
const vaa = Buffer.from(String(process.env[key]), "hex");
|
const vaa = Buffer.from(String(process.env[key]), "hex");
|
||||||
const { foreignChain, module } =
|
const { foreignChain, module } =
|
||||||
parseTokenBridgeRegisterChainVaa(vaa);
|
parseTokenBridgeRegisterChainVaa(vaa);
|
||||||
const chain = coalesceChainName(foreignChain as ChainId);
|
const chain = chainIdToChain(toChainId(foreignChain));
|
||||||
registrations.push({ chain, module });
|
registrations.push({ chain, module });
|
||||||
|
|
||||||
// Register
|
// Register
|
||||||
|
|
|
@ -2,8 +2,8 @@ import { PaginatedObjectsResponse } from "@mysten/sui.js";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { getPackageId, getProvider } from "../../chains/sui";
|
import { getPackageId, getProvider } from "../../chains/sui";
|
||||||
import { NETWORKS, NETWORK_OPTIONS, RPC_OPTIONS } from "../../consts";
|
import { NETWORKS, NETWORK_OPTIONS, RPC_OPTIONS } from "../../consts";
|
||||||
import { assertNetwork } from "../../utils";
|
|
||||||
import { YargsAddCommandsFn } from "../Yargs";
|
import { YargsAddCommandsFn } from "../Yargs";
|
||||||
|
import { getNetwork } from "../../utils";
|
||||||
|
|
||||||
export const addUtilsCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
export const addUtilsCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
y
|
y
|
||||||
|
@ -20,9 +20,8 @@ export const addUtilsCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
.option("network", NETWORK_OPTIONS)
|
.option("network", NETWORK_OPTIONS)
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
const rpc = argv.rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].sui.rpc;
|
|
||||||
const owner = argv.owner;
|
const owner = argv.owner;
|
||||||
|
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
|
@ -61,9 +60,8 @@ export const addUtilsCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
.option("network", NETWORK_OPTIONS)
|
.option("network", NETWORK_OPTIONS)
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
const rpc = argv.rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].sui.rpc;
|
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
console.log(await getPackageId(provider, argv["state-object-id"]));
|
console.log(await getPackageId(provider, argv["state-object-id"]));
|
||||||
}
|
}
|
||||||
|
@ -89,9 +87,8 @@ export const addUtilsCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
} as const)
|
} as const)
|
||||||
.option("rpc", RPC_OPTIONS),
|
.option("rpc", RPC_OPTIONS),
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
const rpc = argv.rpc ?? NETWORKS[network].Sui.rpc;
|
||||||
const rpc = argv.rpc ?? NETWORKS[network].sui.rpc;
|
|
||||||
const provider = getProvider(network, rpc);
|
const provider = getProvider(network, rpc);
|
||||||
console.log(
|
console.log(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
import {
|
|
||||||
isCosmWasmChain,
|
|
||||||
isEVMChain,
|
|
||||||
isTerraChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { impossible } from "../vaa";
|
|
||||||
import { transferEVM } from "../evm";
|
import { transferEVM } from "../evm";
|
||||||
import { CHAIN_NAME_CHOICES, NETWORK_OPTIONS, NETWORKS } from "../consts";
|
import { CHAIN_NAME_CHOICES, NETWORK_OPTIONS, NETWORKS } from "../consts";
|
||||||
import { assertNetwork } from "../utils";
|
|
||||||
import { transferTerra } from "../terra";
|
import { transferTerra } from "../terra";
|
||||||
import { transferInjective } from "../injective";
|
import { transferInjective } from "../injective";
|
||||||
import { transferXpla } from "../xpla";
|
import { transferXpla } from "../xpla";
|
||||||
|
@ -16,6 +9,13 @@ import { transferAlgorand } from "../algorand";
|
||||||
import { transferNear } from "../near";
|
import { transferNear } from "../near";
|
||||||
import { transferSui } from "../chains/sui/transfer";
|
import { transferSui } from "../chains/sui/transfer";
|
||||||
import { transferAptos } from "../aptos";
|
import { transferAptos } from "../aptos";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
PlatformToChains,
|
||||||
|
chainToPlatform,
|
||||||
|
toChain,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { chainToChain, getNetwork } from "../utils";
|
||||||
|
|
||||||
export const command = "transfer";
|
export const command = "transfer";
|
||||||
export const desc = "Transfer a token";
|
export const desc = "Transfer a token";
|
||||||
|
@ -23,12 +23,12 @@ export const builder = (y: typeof yargs) =>
|
||||||
y
|
y
|
||||||
.option("src-chain", {
|
.option("src-chain", {
|
||||||
describe: "source chain",
|
describe: "source chain",
|
||||||
choices: CHAIN_NAME_CHOICES,
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
})
|
})
|
||||||
.option("dst-chain", {
|
.option("dst-chain", {
|
||||||
describe: "destination chain",
|
describe: "destination chain",
|
||||||
choices: CHAIN_NAME_CHOICES,
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
})
|
})
|
||||||
.option("dst-addr", {
|
.option("dst-addr", {
|
||||||
|
@ -58,16 +58,10 @@ export const builder = (y: typeof yargs) =>
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
||||||
) => {
|
) => {
|
||||||
const srcChain = argv["src-chain"];
|
const srcChain: Chain = chainToChain(argv["src-chain"]);
|
||||||
const dstChain = argv["dst-chain"];
|
const dstChain: Chain = chainToChain(argv["dst-chain"]);
|
||||||
if (srcChain === "unset") {
|
|
||||||
throw new Error("source chain is unset");
|
|
||||||
}
|
|
||||||
if (dstChain === "unset") {
|
|
||||||
throw new Error("destination chain is unset");
|
|
||||||
}
|
|
||||||
// TODO: support transfers to sei
|
// TODO: support transfers to sei
|
||||||
if (dstChain === "sei") {
|
if (dstChain === "Sei") {
|
||||||
throw new Error("transfer to sei currently unsupported");
|
throw new Error("transfer to sei currently unsupported");
|
||||||
}
|
}
|
||||||
if (srcChain === dstChain) {
|
if (srcChain === dstChain) {
|
||||||
|
@ -78,19 +72,18 @@ export const handler = async (
|
||||||
throw new Error("amount must be greater than 0");
|
throw new Error("amount must be greater than 0");
|
||||||
}
|
}
|
||||||
const tokenAddr = argv["token-addr"];
|
const tokenAddr = argv["token-addr"];
|
||||||
if (tokenAddr === "native" && isCosmWasmChain(srcChain)) {
|
if (tokenAddr === "native" && chainToPlatform(srcChain) === "Cosmwasm") {
|
||||||
throw new Error(`token-addr must be specified for ${srcChain}`);
|
throw new Error(`token-addr must be specified for ${srcChain}`);
|
||||||
}
|
}
|
||||||
const dstAddr = argv["dst-addr"];
|
const dstAddr = argv["dst-addr"];
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
const rpc = argv.rpc ?? NETWORKS[network][toChain(srcChain)].rpc;
|
||||||
const rpc = argv.rpc ?? NETWORKS[network][srcChain].rpc;
|
|
||||||
if (!rpc) {
|
if (!rpc) {
|
||||||
throw new Error(`No ${network} rpc defined for ${srcChain}`);
|
throw new Error(`No ${network} rpc defined for ${srcChain}`);
|
||||||
}
|
}
|
||||||
if (isEVMChain(srcChain)) {
|
if (chainToPlatform(srcChain) === "Evm") {
|
||||||
await transferEVM(
|
await transferEVM(
|
||||||
srcChain,
|
srcChain as PlatformToChains<"Evm">,
|
||||||
dstChain,
|
dstChain,
|
||||||
dstAddr,
|
dstAddr,
|
||||||
tokenAddr,
|
tokenAddr,
|
||||||
|
@ -98,7 +91,7 @@ export const handler = async (
|
||||||
network,
|
network,
|
||||||
rpc
|
rpc
|
||||||
);
|
);
|
||||||
} else if (isTerraChain(srcChain)) {
|
} else if (srcChain === "Terra" || srcChain === "Terra2") {
|
||||||
await transferTerra(
|
await transferTerra(
|
||||||
srcChain,
|
srcChain,
|
||||||
dstChain,
|
dstChain,
|
||||||
|
@ -108,7 +101,7 @@ export const handler = async (
|
||||||
network,
|
network,
|
||||||
rpc
|
rpc
|
||||||
);
|
);
|
||||||
} else if (srcChain === "solana" || srcChain === "pythnet") {
|
} else if (srcChain === "Solana" || srcChain === "Pythnet") {
|
||||||
await transferSolana(
|
await transferSolana(
|
||||||
srcChain,
|
srcChain,
|
||||||
dstChain,
|
dstChain,
|
||||||
|
@ -118,49 +111,37 @@ export const handler = async (
|
||||||
network,
|
network,
|
||||||
rpc
|
rpc
|
||||||
);
|
);
|
||||||
} else if (srcChain === "algorand") {
|
} else if (srcChain === "Algorand") {
|
||||||
await transferAlgorand(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
await transferAlgorand(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
||||||
} else if (srcChain === "near") {
|
} else if (srcChain === "Near") {
|
||||||
await transferNear(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
await transferNear(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
||||||
} else if (srcChain === "injective") {
|
} else if (srcChain === "Injective") {
|
||||||
await transferInjective(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
await transferInjective(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
||||||
} else if (srcChain === "xpla") {
|
} else if (srcChain === "Xpla") {
|
||||||
await transferXpla(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
await transferXpla(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
||||||
} else if (srcChain === "sei") {
|
} else if (srcChain === "Sei") {
|
||||||
throw new Error("sei is not supported yet");
|
throw new Error("sei is not supported yet");
|
||||||
} else if (srcChain === "osmosis") {
|
} else if (srcChain === "Osmosis") {
|
||||||
throw Error("OSMOSIS is not supported yet");
|
throw Error("OSMOSIS is not supported yet");
|
||||||
} else if (srcChain === "sui") {
|
} else if (srcChain === "Sui") {
|
||||||
await transferSui(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
await transferSui(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
||||||
} else if (srcChain === "aptos") {
|
} else if (srcChain === "Aptos") {
|
||||||
await transferAptos(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
await transferAptos(dstChain, dstAddr, tokenAddr, amount, network, rpc);
|
||||||
} else if (srcChain === "wormchain") {
|
} else if (srcChain === "Wormchain") {
|
||||||
throw Error("Wormchain is not supported yet");
|
throw Error("Wormchain is not supported yet");
|
||||||
} else if (srcChain === "btc") {
|
} else if (srcChain === "Btc") {
|
||||||
throw Error("btc is not supported yet");
|
throw Error("btc is not supported yet");
|
||||||
} else if (srcChain === "cosmoshub") {
|
} else if (srcChain === "Cosmoshub") {
|
||||||
throw Error("cosmoshub is not supported yet");
|
throw Error("cosmoshub is not supported yet");
|
||||||
} else if (srcChain === "evmos") {
|
} else if (srcChain === "Evmos") {
|
||||||
throw Error("evmos is not supported yet");
|
throw Error("evmos is not supported yet");
|
||||||
} else if (srcChain === "kujira") {
|
} else if (srcChain === "Kujira") {
|
||||||
throw Error("kujira is not supported yet");
|
throw Error("kujira is not supported yet");
|
||||||
} else if (srcChain === "neutron") {
|
} else if (srcChain === "Neutron") {
|
||||||
throw Error("neutron is not supported yet");
|
throw Error("neutron is not supported yet");
|
||||||
} else if (srcChain === "celestia") {
|
} else if (srcChain === "Celestia") {
|
||||||
throw Error("celestia is not supported yet");
|
throw Error("celestia is not supported yet");
|
||||||
} else if (srcChain === "stargaze") {
|
|
||||||
throw Error("stargaze is not supported yet");
|
|
||||||
} else if (srcChain === "seda") {
|
|
||||||
throw Error("seda is not supported yet");
|
|
||||||
} else if (srcChain === "dymension") {
|
|
||||||
throw Error("dymension is not supported yet");
|
|
||||||
} else if (srcChain === "provenance") {
|
|
||||||
throw Error("provenance is not supported yet");
|
|
||||||
} else if (srcChain === "rootstock") {
|
|
||||||
throw Error("rootstock is not supported yet");
|
|
||||||
} else {
|
} else {
|
||||||
// If you get a type error here, hover over `chain`'s type and it tells you
|
throw new Error(`${srcChain} is not supported yet`);
|
||||||
// which cases are not handled
|
|
||||||
impossible(srcChain);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// The verify-vaa command invokes the parseAndVerifyVM method on the core contract on Ethereum to verify the specified VAA.
|
// The verify-vaa command invokes the parseAndVerifyVM method on the core contract on Ethereum to verify the specified VAA.
|
||||||
|
|
||||||
import { Implementation__factory } from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
|
import { Implementation__factory } from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
|
||||||
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { NETWORKS, NETWORK_OPTIONS } from "../consts";
|
import { NETWORKS, NETWORK_OPTIONS } from "../consts";
|
||||||
import { assertNetwork } from "../utils";
|
import { getNetwork } from "../utils";
|
||||||
|
import { contracts } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
export const command = "verify-vaa";
|
export const command = "verify-vaa";
|
||||||
export const desc = "Verifies a VAA by querying the core contract on Ethereum";
|
export const desc = "Verifies a VAA by querying the core contract on Ethereum";
|
||||||
|
@ -21,17 +21,16 @@ export const builder = (y: typeof yargs) =>
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
argv: Awaited<ReturnType<typeof builder>["argv"]>
|
||||||
) => {
|
) => {
|
||||||
const network = argv.network.toUpperCase();
|
const network = getNetwork(argv.network);
|
||||||
assertNetwork(network);
|
|
||||||
|
|
||||||
const buf = Buffer.from(String(argv.vaa), "hex");
|
const buf = Buffer.from(String(argv.vaa), "hex");
|
||||||
const contract_address = CONTRACTS[network].ethereum.core;
|
const contract_address = contracts.coreBridge(network, "Ethereum");
|
||||||
if (!contract_address) {
|
if (!contract_address) {
|
||||||
throw Error(`Unknown core contract on ${network} for ethereum`);
|
throw Error(`Unknown core contract on ${network} for ethereum`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const provider = new ethers.providers.JsonRpcProvider(
|
const provider = new ethers.providers.JsonRpcProvider(
|
||||||
NETWORKS[network].ethereum.rpc
|
NETWORKS[network].Ethereum.rpc
|
||||||
);
|
);
|
||||||
const contract = Implementation__factory.connect(contract_address, provider);
|
const contract = Implementation__factory.connect(contract_address, provider);
|
||||||
const result = await contract.parseAndVerifyVM(buf);
|
const result = await contract.parseAndVerifyVM(buf);
|
||||||
|
|
|
@ -1,60 +1,6 @@
|
||||||
import {
|
import { chainToChainId } from "@wormhole-foundation/sdk-base";
|
||||||
CHAIN_ID_SOLANA,
|
|
||||||
CONTRACTS as SDK_CONTRACTS,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
|
|
||||||
const OVERRIDES = {
|
export const GOVERNANCE_CHAIN = chainToChainId("Solana");
|
||||||
MAINNET: {
|
|
||||||
sui: {
|
|
||||||
core: "0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c",
|
|
||||||
token_bridge:
|
|
||||||
"0xc57508ee0d4595e5a8728974a4a93a787d38f339757230d441e895422c07aba9",
|
|
||||||
},
|
|
||||||
aptos: {
|
|
||||||
token_bridge:
|
|
||||||
"0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f",
|
|
||||||
core: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625",
|
|
||||||
nft_bridge:
|
|
||||||
"0x1bdffae984043833ed7fe223f7af7a3f8902d04129b14f801823e64827da7130",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TESTNET: {
|
|
||||||
sui: {
|
|
||||||
core: "0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790",
|
|
||||||
token_bridge:
|
|
||||||
"0x6fb10cdb7aa299e9a4308752dadecb049ff55a892de92992a1edbd7912b3d6da",
|
|
||||||
},
|
|
||||||
aptos: {
|
|
||||||
token_bridge:
|
|
||||||
"0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f",
|
|
||||||
core: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625",
|
|
||||||
nft_bridge: undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DEVNET: {
|
|
||||||
sui: {
|
|
||||||
core: "0x12253210c90f89e7a8525e6c52d41309ff5bfb31f43f561b5fe6f50cd72f9668", // wormhole module State object ID
|
|
||||||
token_bridge:
|
|
||||||
"0x830ed228c6f1bcb40003bb49af3277df2cbf933d63a6bcdcb0ba4580a1a7654e", // token_bridge module State object ID
|
|
||||||
},
|
|
||||||
aptos: {
|
|
||||||
token_bridge:
|
|
||||||
"0x84a5f374d29fc77e370014dce4fd6a55b58ad608de8074b0be5571701724da31",
|
|
||||||
core: "0xde0036a9600559e295d5f6802ef6f3f802f510366e0c23912b0655d972166017",
|
|
||||||
nft_bridge:
|
|
||||||
"0x46da3d4c569388af61f951bdd1153f4c875f90c2991f6b2d0a38e2161a40852c",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(aki): move this to SDK at some point
|
|
||||||
export const CONTRACTS = {
|
|
||||||
MAINNET: { ...SDK_CONTRACTS.MAINNET, ...OVERRIDES.MAINNET },
|
|
||||||
TESTNET: { ...SDK_CONTRACTS.TESTNET, ...OVERRIDES.TESTNET },
|
|
||||||
DEVNET: { ...SDK_CONTRACTS.DEVNET, ...OVERRIDES.DEVNET },
|
|
||||||
};
|
|
||||||
|
|
||||||
export const GOVERNANCE_CHAIN = CHAIN_ID_SOLANA;
|
|
||||||
export const GOVERNANCE_EMITTER =
|
export const GOVERNANCE_EMITTER =
|
||||||
"0000000000000000000000000000000000000000000000000000000000000004";
|
"0000000000000000000000000000000000000000000000000000000000000004";
|
||||||
export const INITIAL_GUARDIAN_DEVNET =
|
export const INITIAL_GUARDIAN_DEVNET =
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ChainName } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
import { Chain } from "@wormhole-foundation/sdk-base";
|
||||||
import { config } from "dotenv";
|
import { config } from "dotenv";
|
||||||
import { homedir } from "os";
|
import { homedir } from "os";
|
||||||
|
|
||||||
|
@ -12,785 +12,773 @@ export type Connection = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ChainConnections = {
|
export type ChainConnections = {
|
||||||
[chain in ChainName]: Connection;
|
[chain in Chain]: Connection;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAINNET = {
|
const Mainnet = {
|
||||||
unset: {
|
Solana: {
|
||||||
rpc: undefined,
|
|
||||||
key: undefined,
|
|
||||||
},
|
|
||||||
solana: {
|
|
||||||
rpc: "https://api.mainnet-beta.solana.com",
|
rpc: "https://api.mainnet-beta.solana.com",
|
||||||
key: getEnvVar("SOLANA_KEY"),
|
key: getEnvVar("SOLANA_KEY"),
|
||||||
},
|
},
|
||||||
terra: {
|
Terra: {
|
||||||
rpc: "https://lcd.terra.dev",
|
rpc: "https://lcd.terra.dev",
|
||||||
chain_id: "columbus-5",
|
chain_id: "columbus-5",
|
||||||
key: getEnvVar("TERRA_MNEMONIC"),
|
key: getEnvVar("TERRA_MNEMONIC"),
|
||||||
},
|
},
|
||||||
ethereum: {
|
Ethereum: {
|
||||||
rpc: `https://rpc.ankr.com/eth`,
|
rpc: `https://rpc.ankr.com/eth`,
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 1,
|
chain_id: 1,
|
||||||
},
|
},
|
||||||
bsc: {
|
Bsc: {
|
||||||
rpc: "https://bsc-dataseed.binance.org/",
|
rpc: "https://bsc-dataseed.binance.org/",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 56,
|
chain_id: 56,
|
||||||
},
|
},
|
||||||
polygon: {
|
Polygon: {
|
||||||
rpc: "https://rpc.ankr.com/polygon",
|
rpc: "https://rpc.ankr.com/polygon",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 137,
|
chain_id: 137,
|
||||||
},
|
},
|
||||||
avalanche: {
|
Avalanche: {
|
||||||
rpc: "https://rpc.ankr.com/avalanche",
|
rpc: "https://rpc.ankr.com/avalanche",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 43114,
|
chain_id: 43114,
|
||||||
},
|
},
|
||||||
algorand: {
|
Algorand: {
|
||||||
rpc: "https://mainnet-api.algonode.cloud",
|
rpc: "https://mainnet-api.algonode.cloud",
|
||||||
key: getEnvVar("ALGORAND_KEY"),
|
key: getEnvVar("ALGORAND_KEY"),
|
||||||
},
|
},
|
||||||
oasis: {
|
Oasis: {
|
||||||
rpc: "https://emerald.oasis.dev/",
|
rpc: "https://emerald.oasis.dev/",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 42262,
|
chain_id: 42262,
|
||||||
},
|
},
|
||||||
fantom: {
|
Fantom: {
|
||||||
rpc: "https://rpc.ftm.tools/",
|
rpc: "https://rpc.ftm.tools/",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 250,
|
chain_id: 250,
|
||||||
},
|
},
|
||||||
aurora: {
|
Aurora: {
|
||||||
rpc: "https://mainnet.aurora.dev",
|
rpc: "https://mainnet.aurora.dev",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 1313161554,
|
chain_id: 1313161554,
|
||||||
},
|
},
|
||||||
karura: {
|
Karura: {
|
||||||
rpc: "https://eth-rpc-karura.aca-api.network/",
|
rpc: "https://eth-rpc-karura.aca-api.network/",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 686,
|
chain_id: 686,
|
||||||
},
|
},
|
||||||
acala: {
|
Acala: {
|
||||||
rpc: "https://eth-rpc-acala.aca-api.network/",
|
rpc: "https://eth-rpc-acala.aca-api.network/",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 787,
|
chain_id: 787,
|
||||||
},
|
},
|
||||||
klaytn: {
|
Klaytn: {
|
||||||
rpc: "https://public-node-api.klaytnapi.com/v1/cypress",
|
rpc: "https://public-node-api.klaytnapi.com/v1/cypress",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 8217,
|
chain_id: 8217,
|
||||||
},
|
},
|
||||||
celo: {
|
Celo: {
|
||||||
rpc: "https://forno.celo.org",
|
rpc: "https://forno.celo.org",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 42220,
|
chain_id: 42220,
|
||||||
},
|
},
|
||||||
near: {
|
Near: {
|
||||||
rpc: "https://rpc.mainnet.near.org",
|
rpc: "https://rpc.mainnet.near.org",
|
||||||
key: getEnvVar("NEAR_KEY"),
|
key: getEnvVar("NEAR_KEY"),
|
||||||
networkId: "mainnet",
|
networkId: "mainnet",
|
||||||
},
|
},
|
||||||
injective: {
|
Injective: {
|
||||||
rpc: "http://sentry0.injective.network:26657",
|
rpc: "http://sentry0.injective.network:26657",
|
||||||
chain_id: "injective-1",
|
chain_id: "injective-1",
|
||||||
key: getEnvVar("INJECTIVE_KEY"),
|
key: getEnvVar("INJECTIVE_KEY"),
|
||||||
},
|
},
|
||||||
osmosis: {
|
Osmosis: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
aptos: {
|
Aptos: {
|
||||||
rpc: "https://fullnode.mainnet.aptoslabs.com/v1",
|
rpc: "https://fullnode.mainnet.aptoslabs.com/v1",
|
||||||
key: getEnvVar("APTOS_KEY"),
|
key: getEnvVar("APTOS_KEY"),
|
||||||
},
|
},
|
||||||
sui: {
|
Sui: {
|
||||||
rpc: "https://fullnode.mainnet.sui.io:443",
|
rpc: "https://fullnode.mainnet.sui.io:443",
|
||||||
key: getEnvVar("SUI_KEY"),
|
key: getEnvVar("SUI_KEY"),
|
||||||
},
|
},
|
||||||
pythnet: {
|
Pythnet: {
|
||||||
rpc: "http://api.pythnet.pyth.network:8899/",
|
rpc: "http://api.pythnet.pyth.network:8899/",
|
||||||
key: getEnvVar("SOLANA_KEY"),
|
key: getEnvVar("SOLANA_KEY"),
|
||||||
},
|
},
|
||||||
xpla: {
|
Xpla: {
|
||||||
rpc: "https://dimension-lcd.xpla.dev",
|
rpc: "https://dimension-lcd.xpla.dev",
|
||||||
chain_id: "dimension_37-1",
|
chain_id: "dimension_37-1",
|
||||||
key: getEnvVar("XPLA_KEY"),
|
key: getEnvVar("XPLA_KEY"),
|
||||||
},
|
},
|
||||||
btc: {
|
Btc: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
wormchain: {
|
Wormchain: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
moonbeam: {
|
Moonbeam: {
|
||||||
rpc: "https://rpc.api.moonbeam.network",
|
rpc: "https://rpc.api.moonbeam.network",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 1284,
|
chain_id: 1284,
|
||||||
},
|
},
|
||||||
neon: {
|
Neon: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
terra2: {
|
Terra2: {
|
||||||
rpc: "https://phoenix-lcd.terra.dev",
|
rpc: "https://phoenix-lcd.terra.dev",
|
||||||
chain_id: "phoenix-1",
|
chain_id: "phoenix-1",
|
||||||
key: getEnvVar("TERRA_MNEMONIC"),
|
key: getEnvVar("TERRA_MNEMONIC"),
|
||||||
},
|
},
|
||||||
arbitrum: {
|
Arbitrum: {
|
||||||
rpc: "https://arb1.arbitrum.io/rpc",
|
rpc: "https://arb1.arbitrum.io/rpc",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 42161,
|
chain_id: 42161,
|
||||||
},
|
},
|
||||||
optimism: {
|
Optimism: {
|
||||||
rpc: "https://mainnet.optimism.io",
|
rpc: "https://mainnet.optimism.io",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 10,
|
chain_id: 10,
|
||||||
},
|
},
|
||||||
gnosis: {
|
Gnosis: {
|
||||||
rpc: "https://rpc.gnosischain.com/",
|
rpc: "https://rpc.gnosischain.com/",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 100,
|
chain_id: 100,
|
||||||
},
|
},
|
||||||
base: {
|
Base: {
|
||||||
rpc: "https://mainnet.base.org",
|
rpc: "https://mainnet.base.org",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 8453,
|
chain_id: 8453,
|
||||||
},
|
},
|
||||||
sei: {
|
Sei: {
|
||||||
rpc: "https://sei-rpc.polkachu.com/",
|
rpc: "https://sei-rpc.polkachu.com/",
|
||||||
key: getEnvVar("SEI_KEY"),
|
key: getEnvVar("SEI_KEY"),
|
||||||
},
|
},
|
||||||
rootstock: {
|
Rootstock: {
|
||||||
rpc: "https://public-node.rsk.co",
|
rpc: "https://public-node.rsk.co",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 30,
|
chain_id: 30,
|
||||||
},
|
},
|
||||||
scroll: {
|
Scroll: {
|
||||||
rpc: "https://rpc.ankr.com/scroll",
|
rpc: "https://rpc.ankr.com/scroll",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 534352,
|
chain_id: 534352,
|
||||||
},
|
},
|
||||||
mantle: {
|
Mantle: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
blast: {
|
Blast: {
|
||||||
rpc: "https://rpc.ankr.com/blast",
|
rpc: "https://rpc.ankr.com/blast",
|
||||||
key: getEnvVar("ETH_KEY"),
|
key: getEnvVar("ETH_KEY"),
|
||||||
chain_id: 81457,
|
chain_id: 81457,
|
||||||
},
|
},
|
||||||
xlayer: {
|
Xlayer: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
linea: {
|
Linea: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
berachain: {
|
Berachain: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
seievm: {
|
Seievm: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
sepolia: {
|
Sepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
holesky: {
|
Holesky: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
cosmoshub: {
|
Cosmoshub: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
evmos: {
|
Evmos: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
kujira: {
|
Kujira: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
neutron: {
|
Neutron: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
celestia: {
|
Celestia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
arbitrum_sepolia: {
|
ArbitrumSepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
base_sepolia: {
|
BaseSepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
optimism_sepolia: {
|
OptimismSepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
polygon_sepolia: {
|
PolygonSepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
stargaze: {
|
Stargaze: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
seda: {
|
Seda: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
dymension: {
|
Dymension: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
provenance: {
|
Provenance: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const TESTNET = {
|
const Testnet = {
|
||||||
unset: {
|
Solana: {
|
||||||
rpc: undefined,
|
|
||||||
key: undefined,
|
|
||||||
},
|
|
||||||
solana: {
|
|
||||||
rpc: "https://api.devnet.solana.com",
|
rpc: "https://api.devnet.solana.com",
|
||||||
key: getEnvVar("SOLANA_KEY_TESTNET"),
|
key: getEnvVar("SOLANA_KEY_TESTNET"),
|
||||||
},
|
},
|
||||||
terra: {
|
Terra: {
|
||||||
rpc: "https://bombay-lcd.terra.dev",
|
rpc: "https://bombay-lcd.terra.dev",
|
||||||
chain_id: "bombay-12",
|
chain_id: "bombay-12",
|
||||||
key: getEnvVar("TERRA_MNEMONIC_TESTNET"),
|
key: getEnvVar("TERRA_MNEMONIC_TESTNET"),
|
||||||
},
|
},
|
||||||
ethereum: {
|
Ethereum: {
|
||||||
rpc: `https://rpc.ankr.com/eth_goerli`,
|
rpc: `https://rpc.ankr.com/eth_goerli`,
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 5,
|
chain_id: 5,
|
||||||
},
|
},
|
||||||
bsc: {
|
Bsc: {
|
||||||
rpc: "https://data-seed-prebsc-1-s1.binance.org:8545",
|
rpc: "https://data-seed-prebsc-1-s1.binance.org:8545",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 97,
|
chain_id: 97,
|
||||||
},
|
},
|
||||||
polygon: {
|
Polygon: {
|
||||||
rpc: `https://rpc.ankr.com/polygon_mumbai`,
|
rpc: `https://rpc.ankr.com/polygon_mumbai`,
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 80001,
|
chain_id: 80001,
|
||||||
},
|
},
|
||||||
avalanche: {
|
Avalanche: {
|
||||||
rpc: "https://rpc.ankr.com/avalanche_fuji",
|
rpc: "https://rpc.ankr.com/avalanche_fuji",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 43113,
|
chain_id: 43113,
|
||||||
},
|
},
|
||||||
oasis: {
|
Oasis: {
|
||||||
rpc: "https://testnet.emerald.oasis.dev",
|
rpc: "https://testnet.emerald.oasis.dev",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 42261,
|
chain_id: 42261,
|
||||||
},
|
},
|
||||||
algorand: {
|
Algorand: {
|
||||||
rpc: "https://testnet-api.algonode.cloud",
|
rpc: "https://testnet-api.algonode.cloud",
|
||||||
key: getEnvVar("ALGORAND_KEY_TESTNET"),
|
key: getEnvVar("ALGORAND_KEY_TESTNET"),
|
||||||
},
|
},
|
||||||
fantom: {
|
Fantom: {
|
||||||
rpc: "https://rpc.testnet.fantom.network",
|
rpc: "https://rpc.testnet.fantom.network",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 4002,
|
chain_id: 4002,
|
||||||
},
|
},
|
||||||
aurora: {
|
Aurora: {
|
||||||
rpc: "https://testnet.aurora.dev",
|
rpc: "https://testnet.aurora.dev",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 1313161555,
|
chain_id: 1313161555,
|
||||||
},
|
},
|
||||||
karura: {
|
Karura: {
|
||||||
rpc: "https://eth-rpc-karura-testnet.aca-staging.network",
|
rpc: "https://eth-rpc-karura-testnet.aca-staging.network",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 596,
|
chain_id: 596,
|
||||||
},
|
},
|
||||||
acala: {
|
Acala: {
|
||||||
rpc: "https://eth-rpc-acala-testnet.aca-staging.network",
|
rpc: "https://eth-rpc-acala-testnet.aca-staging.network",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 595,
|
chain_id: 595,
|
||||||
},
|
},
|
||||||
klaytn: {
|
Klaytn: {
|
||||||
rpc: "https://api.baobab.klaytn.net:8651",
|
rpc: "https://api.baobab.klaytn.net:8651",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 1001,
|
chain_id: 1001,
|
||||||
},
|
},
|
||||||
celo: {
|
Celo: {
|
||||||
rpc: "https://alfajores-forno.celo-testnet.org",
|
rpc: "https://alfajores-forno.celo-testnet.org",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 44787,
|
chain_id: 44787,
|
||||||
},
|
},
|
||||||
near: {
|
Near: {
|
||||||
rpc: "https://rpc.testnet.near.org",
|
rpc: "https://rpc.testnet.near.org",
|
||||||
key: getEnvVar("NEAR_KEY_TESTNET"),
|
key: getEnvVar("NEAR_KEY_TESTNET"),
|
||||||
networkId: "testnet",
|
networkId: "testnet",
|
||||||
},
|
},
|
||||||
injective: {
|
Injective: {
|
||||||
rpc: "https://k8s.testnet.tm.injective.network:443",
|
rpc: "https://k8s.testnet.tm.injective.network:443",
|
||||||
chain_id: "injective-888",
|
chain_id: "injective-888",
|
||||||
key: getEnvVar("INJECTIVE_KEY_TESTNET"),
|
key: getEnvVar("INJECTIVE_KEY_TESTNET"),
|
||||||
},
|
},
|
||||||
osmosis: {
|
Osmosis: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
chain_id: "osmo-test-4",
|
chain_id: "osmo-test-4",
|
||||||
key: getEnvVar("OSMOSIS_KEY_TESTNET"),
|
key: getEnvVar("OSMOSIS_KEY_TESTNET"),
|
||||||
},
|
},
|
||||||
aptos: {
|
Aptos: {
|
||||||
rpc: "https://fullnode.testnet.aptoslabs.com/v1",
|
rpc: "https://fullnode.testnet.aptoslabs.com/v1",
|
||||||
key: getEnvVar("APTOS_TESTNET"),
|
key: getEnvVar("APTOS_TESTNET"),
|
||||||
},
|
},
|
||||||
sui: {
|
Sui: {
|
||||||
rpc: "https://fullnode.testnet.sui.io:443",
|
rpc: "https://fullnode.testnet.sui.io:443",
|
||||||
key: getEnvVar("SUI_KEY_TESTNET"),
|
key: getEnvVar("SUI_KEY_TESTNET"),
|
||||||
},
|
},
|
||||||
pythnet: {
|
Pythnet: {
|
||||||
rpc: "https://api.pythtest.pyth.network/",
|
rpc: "https://api.pythtest.pyth.network/",
|
||||||
key: getEnvVar("SOLANA_KEY_TESTNET"),
|
key: getEnvVar("SOLANA_KEY_TESTNET"),
|
||||||
},
|
},
|
||||||
xpla: {
|
Xpla: {
|
||||||
rpc: "https://cube-lcd.xpla.dev:443",
|
rpc: "https://cube-lcd.xpla.dev:443",
|
||||||
chain_id: "cube_47-5",
|
chain_id: "cube_47-5",
|
||||||
key: getEnvVar("XPLA_KEY_TESTNET"),
|
key: getEnvVar("XPLA_KEY_TESTNET"),
|
||||||
},
|
},
|
||||||
sei: {
|
Sei: {
|
||||||
rpc: "https://rpc.atlantic-2.seinetwork.io",
|
rpc: "https://rpc.atlantic-2.seinetwork.io",
|
||||||
key: getEnvVar("SEI_KEY_TESTNET"),
|
key: getEnvVar("SEI_KEY_TESTNET"),
|
||||||
},
|
},
|
||||||
scroll: {
|
Scroll: {
|
||||||
rpc: "https://rpc.ankr.com/scroll_sepolia_testnet",
|
rpc: "https://rpc.ankr.com/scroll_sepolia_testnet",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 534353,
|
chain_id: 534353,
|
||||||
},
|
},
|
||||||
mantle: {
|
Mantle: {
|
||||||
rpc: "https://mantle-sepolia.drpc.org",
|
rpc: "https://mantle-sepolia.drpc.org",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 5003,
|
chain_id: 5003,
|
||||||
},
|
},
|
||||||
blast: {
|
Blast: {
|
||||||
rpc: "https://blast-sepolia.drpc.org",
|
rpc: "https://blast-sepolia.drpc.org",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 168587773,
|
chain_id: 168587773,
|
||||||
},
|
},
|
||||||
xlayer: {
|
Xlayer: {
|
||||||
rpc: "https://testrpc.xlayer.tech/",
|
rpc: "https://testrpc.xlayer.tech/",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 195,
|
chain_id: 195,
|
||||||
},
|
},
|
||||||
linea: {
|
Linea: {
|
||||||
rpc: "https://rpc.sepolia.linea.build",
|
rpc: "https://rpc.sepolia.linea.build",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 59141,
|
chain_id: 59141,
|
||||||
},
|
},
|
||||||
berachain: {
|
Berachain: {
|
||||||
rpc: "https://artio.rpc.berachain.com/",
|
rpc: "https://artio.rpc.berachain.com/",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 80085,
|
chain_id: 80085,
|
||||||
},
|
},
|
||||||
seievm: {
|
Seievm: {
|
||||||
rpc: "https://evm-rpc-arctic-1.sei-apis.com/",
|
rpc: "https://evm-rpc-arctic-1.sei-apis.com/",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 713715,
|
chain_id: 713715,
|
||||||
},
|
},
|
||||||
sepolia: {
|
Sepolia: {
|
||||||
rpc: "https://rpc.ankr.com/eth_sepolia",
|
rpc: "https://rpc.ankr.com/eth_sepolia",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 11155111,
|
chain_id: 11155111,
|
||||||
},
|
},
|
||||||
holesky: {
|
Holesky: {
|
||||||
rpc: "https://rpc.ankr.com/eth_holesky",
|
rpc: "https://rpc.ankr.com/eth_holesky",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 17000,
|
chain_id: 17000,
|
||||||
},
|
},
|
||||||
btc: {
|
Btc: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
wormchain: {
|
Wormchain: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
moonbeam: {
|
Moonbeam: {
|
||||||
rpc: "https://rpc.api.moonbase.moonbeam.network",
|
rpc: "https://rpc.api.moonbase.moonbeam.network",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 1287,
|
chain_id: 1287,
|
||||||
},
|
},
|
||||||
neon: {
|
Neon: {
|
||||||
rpc: "https://proxy.devnet.neonlabs.org/solana",
|
rpc: "https://proxy.devnet.neonlabs.org/solana",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
terra2: {
|
Terra2: {
|
||||||
rpc: "https://pisco-lcd.terra.dev",
|
rpc: "https://pisco-lcd.terra.dev",
|
||||||
chain_id: "pisco-1",
|
chain_id: "pisco-1",
|
||||||
key: getEnvVar("TERRA_MNEMONIC_TESTNET"),
|
key: getEnvVar("TERRA_MNEMONIC_TESTNET"),
|
||||||
},
|
},
|
||||||
arbitrum: {
|
Arbitrum: {
|
||||||
rpc: "https://goerli-rollup.arbitrum.io/rpc",
|
rpc: "https://goerli-rollup.arbitrum.io/rpc",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 421613,
|
chain_id: 421613,
|
||||||
},
|
},
|
||||||
optimism: {
|
Optimism: {
|
||||||
rpc: "https://goerli.optimism.io",
|
rpc: "https://goerli.optimism.io",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 420,
|
chain_id: 420,
|
||||||
},
|
},
|
||||||
gnosis: {
|
Gnosis: {
|
||||||
rpc: "https://sokol.poa.network/",
|
rpc: "https://sokol.poa.network/",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 77,
|
chain_id: 77,
|
||||||
},
|
},
|
||||||
base: {
|
Base: {
|
||||||
rpc: "https://goerli.base.org",
|
rpc: "https://goerli.base.org",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 84531,
|
chain_id: 84531,
|
||||||
},
|
},
|
||||||
rootstock: {
|
Rootstock: {
|
||||||
rpc: "https://public-node.testnet.rsk.co",
|
rpc: "https://public-node.testnet.rsk.co",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 31,
|
chain_id: 31,
|
||||||
},
|
},
|
||||||
cosmoshub: {
|
Cosmoshub: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
evmos: {
|
Evmos: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
kujira: {
|
Kujira: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
neutron: {
|
Neutron: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
celestia: {
|
Celestia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
arbitrum_sepolia: {
|
ArbitrumSepolia: {
|
||||||
rpc: "https://arbitrum-sepolia.publicnode.com",
|
rpc: "https://arbitrum-sepolia.publicnode.com",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 421614,
|
chain_id: 421614,
|
||||||
},
|
},
|
||||||
base_sepolia: {
|
BaseSepolia: {
|
||||||
rpc: "https://sepolia.base.org",
|
rpc: "https://sepolia.base.org",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 84532,
|
chain_id: 84532,
|
||||||
},
|
},
|
||||||
optimism_sepolia: {
|
OptimismSepolia: {
|
||||||
rpc: "https://rpc.ankr.com/optimism_sepolia",
|
rpc: "https://rpc.ankr.com/optimism_sepolia",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 11155420,
|
chain_id: 11155420,
|
||||||
},
|
},
|
||||||
polygon_sepolia: {
|
PolygonSepolia: {
|
||||||
rpc: "https://rpc-amoy.polygon.technology/",
|
rpc: "https://rpc-amoy.polygon.technology/",
|
||||||
key: getEnvVar("ETH_KEY_TESTNET"),
|
key: getEnvVar("ETH_KEY_TESTNET"),
|
||||||
chain_id: 80002,
|
chain_id: 80002,
|
||||||
},
|
},
|
||||||
stargaze: {
|
Stargaze: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
seda: {
|
Seda: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
dymension: {
|
Dymension: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
provenance: {
|
Provenance: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEVNET = {
|
const Devnet = {
|
||||||
unset: {
|
Solana: {
|
||||||
rpc: undefined,
|
|
||||||
key: undefined,
|
|
||||||
},
|
|
||||||
solana: {
|
|
||||||
rpc: "http://localhost:8899",
|
rpc: "http://localhost:8899",
|
||||||
key: "J2D4pwDred8P9ioyPEZVLPht885AeYpifsFGUyuzVmiKQosAvmZP4EegaKFrSprBC5vVP1xTvu61vYDWsxBNsYx",
|
key: "J2D4pwDred8P9ioyPEZVLPht885AeYpifsFGUyuzVmiKQosAvmZP4EegaKFrSprBC5vVP1xTvu61vYDWsxBNsYx",
|
||||||
},
|
},
|
||||||
terra: {
|
Terra: {
|
||||||
rpc: "http://localhost:1317",
|
rpc: "http://localhost:1317",
|
||||||
chain_id: "columbus-5",
|
chain_id: "columbus-5",
|
||||||
key: "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius",
|
key: "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius",
|
||||||
},
|
},
|
||||||
ethereum: {
|
Ethereum: {
|
||||||
rpc: "http://localhost:8545",
|
rpc: "http://localhost:8545",
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
bsc: {
|
Bsc: {
|
||||||
rpc: "http://localhost:8546",
|
rpc: "http://localhost:8546",
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
polygon: {
|
Polygon: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
avalanche: {
|
Avalanche: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
oasis: {
|
Oasis: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
algorand: {
|
Algorand: {
|
||||||
rpc: "http://localhost",
|
rpc: "http://localhost",
|
||||||
key: getEnvVar("ALGORAND_KEY_DEVNET"),
|
key: getEnvVar("ALGORAND_KEY_DEVNET"),
|
||||||
},
|
},
|
||||||
fantom: {
|
Fantom: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
aurora: {
|
Aurora: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
karura: {
|
Karura: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
acala: {
|
Acala: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
klaytn: {
|
Klaytn: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
celo: {
|
Celo: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
near: {
|
Near: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
networkId: "sandbox",
|
networkId: "sandbox",
|
||||||
},
|
},
|
||||||
injective: {
|
Injective: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
osmosis: {
|
Osmosis: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
pythnet: {
|
Pythnet: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
btc: {
|
Btc: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
xpla: {
|
Xpla: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
sei: {
|
Sei: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
scroll: {
|
Scroll: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
mantle: {
|
Mantle: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
blast: {
|
Blast: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
xlayer: {
|
Xlayer: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
linea: {
|
Linea: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
berachain: {
|
Berachain: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
seievm: {
|
Seievm: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
sepolia: {
|
Sepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
holesky: {
|
Holesky: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
wormchain: {
|
Wormchain: {
|
||||||
rpc: "http://localhost:1319",
|
rpc: "http://localhost:1319",
|
||||||
chain_id: "wormchain",
|
chain_id: "wormchain",
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
aptos: {
|
Aptos: {
|
||||||
rpc: "http://0.0.0.0:8080",
|
rpc: "http://0.0.0.0:8080",
|
||||||
key: "537c1f91e56891445b491068f519b705f8c0f1a1e66111816dd5d4aa85b8113d",
|
key: "537c1f91e56891445b491068f519b705f8c0f1a1e66111816dd5d4aa85b8113d",
|
||||||
},
|
},
|
||||||
sui: {
|
Sui: {
|
||||||
rpc: "http://0.0.0.0:9000",
|
rpc: "http://0.0.0.0:9000",
|
||||||
key: "AGA20wtGcwbcNAG4nwapbQ5wIuXwkYQEWFUoSVAxctHb",
|
key: "AGA20wtGcwbcNAG4nwapbQ5wIuXwkYQEWFUoSVAxctHb",
|
||||||
},
|
},
|
||||||
moonbeam: {
|
Moonbeam: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
neon: {
|
Neon: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
key: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
|
||||||
},
|
},
|
||||||
terra2: {
|
Terra2: {
|
||||||
rpc: "http://localhost:1318",
|
rpc: "http://localhost:1318",
|
||||||
chain_id: "phoenix-1",
|
chain_id: "phoenix-1",
|
||||||
key: "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius",
|
key: "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius",
|
||||||
},
|
},
|
||||||
arbitrum: {
|
Arbitrum: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
optimism: {
|
Optimism: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
gnosis: {
|
Gnosis: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
base: {
|
Base: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
rootstock: {
|
Rootstock: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
cosmoshub: {
|
Cosmoshub: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
evmos: {
|
Evmos: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
kujira: {
|
Kujira: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
},
|
},
|
||||||
neutron: {
|
Neutron: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
celestia: {
|
Celestia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
arbitrum_sepolia: {
|
ArbitrumSepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
base_sepolia: {
|
BaseSepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
optimism_sepolia: {
|
OptimismSepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
polygon_sepolia: {
|
PolygonSepolia: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
stargaze: {
|
Stargaze: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
seda: {
|
Seda: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
dymension: {
|
Dymension: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
},
|
},
|
||||||
provenance: {
|
Provenance: {
|
||||||
rpc: undefined,
|
rpc: undefined,
|
||||||
key: undefined,
|
key: undefined,
|
||||||
chain_id: undefined,
|
chain_id: undefined,
|
||||||
|
@ -811,18 +799,18 @@ const DEVNET = {
|
||||||
*
|
*
|
||||||
* (Do not delete this declaration!)
|
* (Do not delete this declaration!)
|
||||||
*/
|
*/
|
||||||
const isTestnetConnections: ChainConnections = TESTNET;
|
const isTestnetConnections: ChainConnections = Testnet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* See [[isTestnetContracts]]
|
* See [[isTestnetContracts]]
|
||||||
*/
|
*/
|
||||||
const isMainnetConnections: ChainConnections = MAINNET;
|
const isMainnetConnections: ChainConnections = Mainnet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* See [[isTestnetContracts]]
|
* See [[isTestnetContracts]]
|
||||||
*/
|
*/
|
||||||
const isDevnetConnections: ChainConnections = DEVNET;
|
const isDevnetConnections: ChainConnections = Devnet;
|
||||||
|
|
||||||
export const NETWORKS = { MAINNET, TESTNET, DEVNET };
|
export const NETWORKS = { Mainnet, Testnet, Devnet };
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import {
|
import {
|
||||||
CHAINS,
|
Chain,
|
||||||
ChainId,
|
ChainId,
|
||||||
ChainName,
|
chainIds,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
chains,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
export const DEBUG_OPTIONS = {
|
export const DEBUG_OPTIONS = {
|
||||||
alias: "d",
|
alias: "d",
|
||||||
|
@ -38,11 +39,9 @@ export const RPC_OPTIONS = {
|
||||||
demandOption: false,
|
demandOption: false,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const CHAIN_ID_OR_NAME_CHOICES = [
|
export const CHAIN_ID_OR_NAME_CHOICES = [...chains, ...chainIds] as (
|
||||||
...Object.keys(CHAINS),
|
| Chain
|
||||||
...Object.values(CHAINS),
|
| ChainId
|
||||||
] as (ChainName | ChainId)[];
|
)[];
|
||||||
|
|
||||||
export const CHAIN_NAME_CHOICES = Object.keys(CHAINS).filter(
|
export const CHAIN_NAME_CHOICES = [...chains];
|
||||||
(c) => c !== "unset"
|
|
||||||
) as ChainName[];
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
import {
|
|
||||||
ChainId,
|
|
||||||
ChainName,
|
|
||||||
isCosmWasmChain,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getEmitterAddressAlgorand,
|
getEmitterAddressAlgorand,
|
||||||
getEmitterAddressEth,
|
getEmitterAddressEth,
|
||||||
|
@ -11,21 +5,25 @@ import {
|
||||||
getEmitterAddressSolana,
|
getEmitterAddressSolana,
|
||||||
getEmitterAddressTerra,
|
getEmitterAddressTerra,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/bridge/getEmitterAddress";
|
} from "@certusone/wormhole-sdk/lib/esm/bridge/getEmitterAddress";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
ChainId,
|
||||||
|
chainToPlatform,
|
||||||
|
toChain,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
|
||||||
export async function getEmitterAddress(
|
export async function getEmitterAddress(chain: ChainId | Chain, addr: string) {
|
||||||
chain: ChainId | ChainName,
|
const localChain = toChain(chain);
|
||||||
addr: string
|
if (localChain === "Solana" || localChain === "Pythnet") {
|
||||||
) {
|
|
||||||
if (chain === "solana" || chain === "pythnet") {
|
|
||||||
// TODO: Create an isSolanaChain()
|
// TODO: Create an isSolanaChain()
|
||||||
addr = getEmitterAddressSolana(addr);
|
addr = getEmitterAddressSolana(addr);
|
||||||
} else if (isCosmWasmChain(chain)) {
|
} else if (chainToPlatform(localChain) === "Cosmwasm") {
|
||||||
addr = await getEmitterAddressTerra(addr);
|
addr = await getEmitterAddressTerra(addr);
|
||||||
} else if (chain === "algorand") {
|
} else if (localChain === "Algorand") {
|
||||||
addr = getEmitterAddressAlgorand(BigInt(addr));
|
addr = getEmitterAddressAlgorand(BigInt(addr));
|
||||||
} else if (chain === "near") {
|
} else if (localChain === "Near") {
|
||||||
addr = getEmitterAddressNear(addr);
|
addr = getEmitterAddressNear(addr);
|
||||||
} else if (chain === "aptos") {
|
} else if (localChain === "Aptos") {
|
||||||
// TODO: There should be something in the SDK to do this.
|
// TODO: There should be something in the SDK to do this.
|
||||||
if (
|
if (
|
||||||
addr ===
|
addr ===
|
||||||
|
@ -42,7 +40,7 @@ export async function getEmitterAddress(
|
||||||
} else {
|
} else {
|
||||||
throw Error(`Unsupported Aptos address: ${addr}`);
|
throw Error(`Unsupported Aptos address: ${addr}`);
|
||||||
}
|
}
|
||||||
} else if (chain === "sui") {
|
} else if (localChain === "Sui") {
|
||||||
// TODO: There should be something in the SDK to do this.
|
// TODO: There should be something in the SDK to do this.
|
||||||
if (
|
if (
|
||||||
addr ===
|
addr ===
|
||||||
|
|
|
@ -5,20 +5,10 @@ import {
|
||||||
NFTBridgeImplementation__factory,
|
NFTBridgeImplementation__factory,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
|
} from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
|
||||||
import { WormholeRelayer__factory } from "@certusone/wormhole-sdk/lib/esm/ethers-relayer-contracts";
|
import { WormholeRelayer__factory } from "@certusone/wormhole-sdk/lib/esm/ethers-relayer-contracts";
|
||||||
import { getWormholeRelayerAddress } from "@certusone/wormhole-sdk/lib/esm/relayer";
|
|
||||||
import {
|
|
||||||
CHAINS,
|
|
||||||
CONTRACTS,
|
|
||||||
ChainName,
|
|
||||||
Contracts,
|
|
||||||
EVMChainName,
|
|
||||||
toChainId,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { solidityKeccak256 } from "ethers/lib/utils";
|
import { solidityKeccak256 } from "ethers/lib/utils";
|
||||||
import { NETWORKS } from "./consts";
|
import { NETWORKS } from "./consts";
|
||||||
import { Network } from "./utils";
|
|
||||||
import { Encoding, Payload, encode, impossible, typeWidth } from "./vaa";
|
import { Encoding, Payload, encode, impossible, typeWidth } from "./vaa";
|
||||||
import {
|
import {
|
||||||
approveEth,
|
approveEth,
|
||||||
|
@ -26,14 +16,22 @@ import {
|
||||||
transferFromEth,
|
transferFromEth,
|
||||||
transferFromEthNative,
|
transferFromEthNative,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
||||||
import { tryNativeToUint8Array } from "@certusone/wormhole-sdk/lib/esm/utils";
|
import {
|
||||||
|
Chain,
|
||||||
|
Network,
|
||||||
|
PlatformToChains,
|
||||||
|
chainToChainId,
|
||||||
|
chains,
|
||||||
|
contracts,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { tryNativeToUint8Array } from "./sdk/array";
|
||||||
|
|
||||||
const _IMPLEMENTATION_SLOT =
|
const _IMPLEMENTATION_SLOT =
|
||||||
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
|
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
|
||||||
|
|
||||||
export async function query_contract_evm(
|
export async function query_contract_evm(
|
||||||
network: Network,
|
network: Network,
|
||||||
chain: EVMChainName,
|
chain: PlatformToChains<"Evm">,
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge",
|
module: "Core" | "NFTBridge" | "TokenBridge",
|
||||||
contract_address: string | undefined,
|
contract_address: string | undefined,
|
||||||
_rpc: string | undefined
|
_rpc: string | undefined
|
||||||
|
@ -44,12 +42,13 @@ export async function query_contract_evm(
|
||||||
throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`);
|
throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const contracts: Contracts = CONTRACTS[network][chain];
|
|
||||||
const provider = new ethers.providers.JsonRpcProvider(rpc);
|
const provider = new ethers.providers.JsonRpcProvider(rpc);
|
||||||
const result: any = {};
|
const result: any = {};
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "Core":
|
case "Core":
|
||||||
contract_address = contract_address ? contract_address : contracts.core;
|
contract_address = contract_address
|
||||||
|
? contract_address
|
||||||
|
: contracts.coreBridge.get(network, chain);
|
||||||
if (!contract_address) {
|
if (!contract_address) {
|
||||||
throw Error(`Unknown core contract on ${network} for ${chain}`);
|
throw Error(`Unknown core contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -105,7 +104,7 @@ export async function query_contract_evm(
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
contract_address = contract_address
|
contract_address = contract_address
|
||||||
? contract_address
|
? contract_address
|
||||||
: contracts.token_bridge;
|
: contracts.tokenBridge.get(network, chain);
|
||||||
if (contract_address === undefined) {
|
if (contract_address === undefined) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
|
throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -115,11 +114,11 @@ export async function query_contract_evm(
|
||||||
);
|
);
|
||||||
result.address = contract_address;
|
result.address = contract_address;
|
||||||
const registrationsPromise = Promise.all(
|
const registrationsPromise = Promise.all(
|
||||||
Object.entries(CHAINS)
|
chains
|
||||||
.filter(([c_name, _]) => c_name !== chain && c_name !== "unset")
|
.filter((c_name) => c_name !== chain)
|
||||||
.map(async ([c_name, c_id]) => [
|
.map(async (c_name) => [
|
||||||
c_name,
|
c_name,
|
||||||
await tb.bridgeContracts(c_id),
|
await tb.bridgeContracts(chainToChainId(c_name)),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
const [
|
const [
|
||||||
|
@ -167,7 +166,7 @@ export async function query_contract_evm(
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
contract_address = contract_address
|
contract_address = contract_address
|
||||||
? contract_address
|
? contract_address
|
||||||
: contracts.nft_bridge;
|
: contracts.nftBridge.get(network, chain);
|
||||||
if (contract_address === undefined) {
|
if (contract_address === undefined) {
|
||||||
throw Error(`Unknown nft bridge contract on ${network} for ${chain}`);
|
throw Error(`Unknown nft bridge contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -177,11 +176,11 @@ export async function query_contract_evm(
|
||||||
);
|
);
|
||||||
result.address = contract_address;
|
result.address = contract_address;
|
||||||
const registrationsPromiseNb = Promise.all(
|
const registrationsPromiseNb = Promise.all(
|
||||||
Object.entries(CHAINS)
|
chains
|
||||||
.filter(([c_name, _]) => c_name !== chain && c_name !== "unset")
|
.filter(([c_name, _]) => c_name !== chain)
|
||||||
.map(async ([c_name, c_id]) => [
|
.map(async (c_name) => [
|
||||||
c_name,
|
c_name,
|
||||||
await nb.bridgeContracts(c_id),
|
await nb.bridgeContracts(chainToChainId(c_name)),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
const [
|
const [
|
||||||
|
@ -232,7 +231,7 @@ export async function query_contract_evm(
|
||||||
|
|
||||||
export async function getImplementation(
|
export async function getImplementation(
|
||||||
network: Network,
|
network: Network,
|
||||||
chain: EVMChainName,
|
chain: PlatformToChains<"Evm">,
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge",
|
module: "Core" | "NFTBridge" | "TokenBridge",
|
||||||
contract_address: string | undefined,
|
contract_address: string | undefined,
|
||||||
_rpc: string | undefined
|
_rpc: string | undefined
|
||||||
|
@ -243,20 +242,21 @@ export async function getImplementation(
|
||||||
throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`);
|
throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const contracts: Contracts = CONTRACTS[network][chain];
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "Core":
|
case "Core":
|
||||||
contract_address = contract_address ? contract_address : contracts.core;
|
contract_address = contract_address
|
||||||
|
? contract_address
|
||||||
|
: contracts.coreBridge.get(network, chain);
|
||||||
break;
|
break;
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
contract_address = contract_address
|
contract_address = contract_address
|
||||||
? contract_address
|
? contract_address
|
||||||
: contracts.token_bridge;
|
: contracts.tokenBridge.get(network, chain);
|
||||||
break;
|
break;
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
contract_address = contract_address
|
contract_address = contract_address
|
||||||
? contract_address
|
? contract_address
|
||||||
: contracts.nft_bridge;
|
: contracts.nftBridge.get(network, chain);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
impossible(module);
|
impossible(module);
|
||||||
|
@ -271,10 +271,14 @@ export async function getImplementation(
|
||||||
)[0];
|
)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSigner(chain: EVMChainName, key: string, rpc: string) {
|
async function getSigner(
|
||||||
|
chain: PlatformToChains<"Evm">,
|
||||||
|
key: string,
|
||||||
|
rpc: string
|
||||||
|
) {
|
||||||
let provider: ethers.providers.JsonRpcProvider;
|
let provider: ethers.providers.JsonRpcProvider;
|
||||||
let signer: ethers.Wallet;
|
let signer: ethers.Wallet;
|
||||||
if (chain === "celo") {
|
if (chain === "Celo") {
|
||||||
provider = new celo.CeloProvider(rpc);
|
provider = new celo.CeloProvider(rpc);
|
||||||
await provider.ready;
|
await provider.ready;
|
||||||
signer = new celo.CeloWallet(key, provider);
|
signer = new celo.CeloWallet(key, provider);
|
||||||
|
@ -286,15 +290,15 @@ async function getSigner(chain: EVMChainName, key: string, rpc: string) {
|
||||||
// NOTE: some of these might have only been tested on mainnet. If it fails in
|
// NOTE: some of these might have only been tested on mainnet. If it fails in
|
||||||
// testnet (or devnet), they might require additional guards
|
// testnet (or devnet), they might require additional guards
|
||||||
let overrides: ethers.Overrides = {};
|
let overrides: ethers.Overrides = {};
|
||||||
if (chain === "karura" || chain == "acala") {
|
if (chain === "Karura" || chain == "Acala") {
|
||||||
overrides = await getKaruraGasParams(rpc);
|
overrides = await getKaruraGasParams(rpc);
|
||||||
} else if (chain === "polygon") {
|
} else if (chain === "Polygon") {
|
||||||
const feeData = await provider.getFeeData();
|
const feeData = await provider.getFeeData();
|
||||||
overrides = {
|
overrides = {
|
||||||
maxFeePerGas: feeData.maxFeePerGas?.mul(50) || undefined,
|
maxFeePerGas: feeData.maxFeePerGas?.mul(50) || undefined,
|
||||||
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas?.mul(50) || undefined,
|
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas?.mul(50) || undefined,
|
||||||
};
|
};
|
||||||
} else if (chain === "klaytn" || chain === "fantom") {
|
} else if (chain === "Klaytn" || chain === "Fantom") {
|
||||||
overrides = { gasPrice: (await signer.getGasPrice()).toString() };
|
overrides = { gasPrice: (await signer.getGasPrice()).toString() };
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
@ -308,7 +312,7 @@ export async function execute_evm(
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
vaa: Buffer,
|
vaa: Buffer,
|
||||||
network: Network,
|
network: Network,
|
||||||
chain: EVMChainName,
|
chain: PlatformToChains<"Evm">,
|
||||||
contract_address: string | undefined,
|
contract_address: string | undefined,
|
||||||
_rpc: string | undefined
|
_rpc: string | undefined
|
||||||
) {
|
) {
|
||||||
|
@ -323,12 +327,14 @@ export async function execute_evm(
|
||||||
}
|
}
|
||||||
|
|
||||||
const key: string = n.key;
|
const key: string = n.key;
|
||||||
const contracts: Contracts = CONTRACTS[network][chain];
|
// const contracts: Contracts = CONTRACTS[network][chain];
|
||||||
const { signer, overrides } = await getSigner(chain, key, rpc);
|
const { signer, overrides } = await getSigner(chain, key, rpc);
|
||||||
|
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
contract_address = contract_address ? contract_address : contracts.core;
|
contract_address = contract_address
|
||||||
|
? contract_address
|
||||||
|
: contracts.coreBridge.get(network, chain);
|
||||||
if (contract_address === undefined) {
|
if (contract_address === undefined) {
|
||||||
throw Error(`Unknown core contract on ${network} for ${chain}`);
|
throw Error(`Unknown core contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -362,7 +368,7 @@ export async function execute_evm(
|
||||||
case "NFTBridge": {
|
case "NFTBridge": {
|
||||||
contract_address = contract_address
|
contract_address = contract_address
|
||||||
? contract_address
|
? contract_address
|
||||||
: contracts.nft_bridge;
|
: contracts.nftBridge.get(network, chain);
|
||||||
if (contract_address === undefined) {
|
if (contract_address === undefined) {
|
||||||
throw Error(`Unknown nft bridge contract on ${network} for ${chain}`);
|
throw Error(`Unknown nft bridge contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -401,7 +407,7 @@ export async function execute_evm(
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
contract_address = contract_address
|
contract_address = contract_address
|
||||||
? contract_address
|
? contract_address
|
||||||
: contracts.token_bridge;
|
: contracts.tokenBridge.get(network, chain);
|
||||||
if (contract_address === undefined) {
|
if (contract_address === undefined) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
|
throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -451,7 +457,7 @@ export async function execute_evm(
|
||||||
case "WormholeRelayer":
|
case "WormholeRelayer":
|
||||||
contract_address = contract_address
|
contract_address = contract_address
|
||||||
? contract_address
|
? contract_address
|
||||||
: getWormholeRelayerAddress(chain, network);
|
: contracts.relayer.get(network, chain);
|
||||||
if (contract_address === undefined) {
|
if (contract_address === undefined) {
|
||||||
throw Error(
|
throw Error(
|
||||||
`Unknown Wormhole Relayer contract on ${network} for ${chain}`
|
`Unknown Wormhole Relayer contract on ${network} for ${chain}`
|
||||||
|
@ -493,8 +499,8 @@ export async function execute_evm(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transferEVM(
|
export async function transferEVM(
|
||||||
srcChain: EVMChainName,
|
srcChain: PlatformToChains<"Evm">,
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
|
@ -505,7 +511,7 @@ export async function transferEVM(
|
||||||
if (!n.key) {
|
if (!n.key) {
|
||||||
throw Error(`No ${network} key defined for ${srcChain} (see networks.ts)`);
|
throw Error(`No ${network} key defined for ${srcChain} (see networks.ts)`);
|
||||||
}
|
}
|
||||||
const { token_bridge } = CONTRACTS[network][srcChain];
|
const token_bridge = contracts.tokenBridge.get(network, srcChain);
|
||||||
if (!token_bridge) {
|
if (!token_bridge) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for ${srcChain}`);
|
throw Error(`Unknown token bridge contract on ${network} for ${srcChain}`);
|
||||||
}
|
}
|
||||||
|
@ -516,8 +522,8 @@ export async function transferEVM(
|
||||||
token_bridge,
|
token_bridge,
|
||||||
signer,
|
signer,
|
||||||
amount,
|
amount,
|
||||||
toChainId(dstChain),
|
chainToChainId(dstChain),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain)
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const allowance = await getAllowanceEth(token_bridge, tokenAddress, signer);
|
const allowance = await getAllowanceEth(token_bridge, tokenAddress, signer);
|
||||||
|
@ -529,8 +535,8 @@ export async function transferEVM(
|
||||||
signer,
|
signer,
|
||||||
tokenAddress,
|
tokenAddress,
|
||||||
amount,
|
amount,
|
||||||
dstChain,
|
chainToChainId(dstChain),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain),
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain)),
|
||||||
undefined,
|
undefined,
|
||||||
overrides
|
overrides
|
||||||
);
|
);
|
||||||
|
@ -828,11 +834,10 @@ const isUnsupportedError = (e: any): e is { reason: string } =>
|
||||||
|
|
||||||
export async function queryRegistrationsEvm(
|
export async function queryRegistrationsEvm(
|
||||||
network: Network,
|
network: Network,
|
||||||
chain: EVMChainName,
|
chain: PlatformToChains<"Evm">,
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge"
|
module: "Core" | "NFTBridge" | "TokenBridge"
|
||||||
): Promise<Object> {
|
): Promise<Object> {
|
||||||
const n = NETWORKS[network][chain];
|
const n = NETWORKS[network][chain];
|
||||||
const contracts = CONTRACTS[network][chain];
|
|
||||||
|
|
||||||
let targetContract: string | undefined;
|
let targetContract: string | undefined;
|
||||||
let contract: any;
|
let contract: any;
|
||||||
|
@ -841,7 +846,7 @@ export async function queryRegistrationsEvm(
|
||||||
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
targetContract = contracts.token_bridge;
|
targetContract = contracts.tokenBridge.get(network, chain);
|
||||||
if (targetContract === undefined) {
|
if (targetContract === undefined) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
|
throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -851,7 +856,7 @@ export async function queryRegistrationsEvm(
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
targetContract = contracts.nft_bridge;
|
targetContract = contracts.nftBridge.get(network, chain);
|
||||||
if (targetContract === undefined) {
|
if (targetContract === undefined) {
|
||||||
throw Error(`Unknown NFT bridge contract on ${network} for ${chain}`);
|
throw Error(`Unknown NFT bridge contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -865,9 +870,12 @@ export async function queryRegistrationsEvm(
|
||||||
}
|
}
|
||||||
|
|
||||||
const registrations: string[][] = await Promise.all(
|
const registrations: string[][] = await Promise.all(
|
||||||
Object.entries(CHAINS)
|
chains
|
||||||
.filter(([cname, _]) => cname !== chain && cname !== "unset")
|
.filter((cname) => cname !== chain)
|
||||||
.map(async ([cname, cid]) => [cname, await contract.bridgeContracts(cid)])
|
.map(async (cname) => [
|
||||||
|
cname,
|
||||||
|
await contract.bridgeContracts(chainToChainId(cname)),
|
||||||
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
const results: { [key: string]: string } = {};
|
const results: { [key: string]: string } = {};
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
import {
|
|
||||||
CHAINS,
|
|
||||||
CONTRACTS,
|
|
||||||
ChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import {
|
import {
|
||||||
getNetworkInfo,
|
getNetworkInfo,
|
||||||
Network as InjectiveNetwork,
|
Network as InjectiveNetwork,
|
||||||
|
@ -19,28 +14,33 @@ import {
|
||||||
import { DEFAULT_STD_FEE, getStdFee } from "@injectivelabs/utils";
|
import { DEFAULT_STD_FEE, getStdFee } from "@injectivelabs/utils";
|
||||||
import { fromUint8Array } from "js-base64";
|
import { fromUint8Array } from "js-base64";
|
||||||
import { NETWORKS } from "./consts";
|
import { NETWORKS } from "./consts";
|
||||||
import { Network } from "./utils";
|
|
||||||
import { impossible, Payload } from "./vaa";
|
import { impossible, Payload } from "./vaa";
|
||||||
import { transferFromInjective } from "@certusone/wormhole-sdk/lib/esm/token_bridge/injective";
|
import { transferFromInjective } from "@certusone/wormhole-sdk/lib/esm/token_bridge/injective";
|
||||||
import { tryNativeToUint8Array } from "@certusone/wormhole-sdk/lib/esm/utils";
|
import {
|
||||||
|
Chain,
|
||||||
|
chainToChainId,
|
||||||
|
contracts,
|
||||||
|
Network,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { chains } from "@wormhole-foundation/sdk";
|
||||||
|
import { tryNativeToUint8Array } from "./sdk/array";
|
||||||
|
|
||||||
export async function execute_injective(
|
export async function execute_injective(
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
vaa: Buffer,
|
vaa: Buffer,
|
||||||
network: Network
|
network: Network
|
||||||
) {
|
) {
|
||||||
if (network === "DEVNET") {
|
if (network === "Devnet") {
|
||||||
throw new Error("Injective is not supported in DEVNET");
|
throw new Error("Injective is not supported in DEVNET");
|
||||||
}
|
}
|
||||||
const chain = "injective";
|
const chain = "Injective";
|
||||||
let { key } = NETWORKS[network][chain];
|
let { key } = NETWORKS[network][chain];
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for Injective`);
|
throw Error(`No ${network} key defined for Injective`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let contracts = CONTRACTS[network][chain];
|
|
||||||
const endPoint =
|
const endPoint =
|
||||||
network === "MAINNET"
|
network === "Mainnet"
|
||||||
? InjectiveNetwork.MainnetK8s
|
? InjectiveNetwork.MainnetK8s
|
||||||
: InjectiveNetwork.TestnetK8s;
|
: InjectiveNetwork.TestnetK8s;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ export async function execute_injective(
|
||||||
|
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
target_contract = contracts.core;
|
target_contract = contracts.coreBridge(network, "Injective");
|
||||||
action = "submit_v_a_a";
|
action = "submit_v_a_a";
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
vaa: fromUint8Array(vaa),
|
vaa: fromUint8Array(vaa),
|
||||||
|
@ -76,14 +76,15 @@ export async function execute_injective(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "NFTBridge": {
|
case "NFTBridge": {
|
||||||
if (!contracts.nft_bridge) {
|
const nftContract = contracts.nftBridge.get(network, "Injective");
|
||||||
|
if (!nftContract) {
|
||||||
// NOTE: this code can safely be removed once the injective NFT bridge is
|
// NOTE: this code can safely be removed once the injective NFT bridge is
|
||||||
// released, but it's fine for it to stay, as the condition will just be
|
// released, but it's fine for it to stay, as the condition will just be
|
||||||
// skipped once 'contracts.nft_bridge' is defined
|
// skipped once 'contracts.nft_bridge' is defined
|
||||||
throw new Error("NFT bridge not supported yet for injective");
|
throw new Error("NFT bridge not supported yet for injective");
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.nft_bridge;
|
target_contract = nftContract;
|
||||||
action = "submit_vaa";
|
action = "submit_vaa";
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
data: fromUint8Array(vaa),
|
data: fromUint8Array(vaa),
|
||||||
|
@ -107,12 +108,12 @@ export async function execute_injective(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
console.log("contracts:", contracts);
|
const tbContract = contracts.tokenBridge.get(network, "Injective");
|
||||||
if (!contracts.token_bridge) {
|
if (!tbContract) {
|
||||||
throw new Error("contracts.token_bridge is undefined");
|
throw new Error("contracts.token_bridge is undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.token_bridge;
|
target_contract = tbContract;
|
||||||
action = "submit_vaa";
|
action = "submit_vaa";
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
data: fromUint8Array(vaa),
|
data: fromUint8Array(vaa),
|
||||||
|
@ -165,22 +166,22 @@ export async function execute_injective(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transferInjective(
|
export async function transferInjective(
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
network: Network,
|
network: Network,
|
||||||
rpc: string
|
rpc: string
|
||||||
) {
|
) {
|
||||||
if (network === "DEVNET") {
|
if (network === "Devnet") {
|
||||||
throw new Error("Injective is not supported in DEVNET");
|
throw new Error("Injective is not supported in DEVNET");
|
||||||
}
|
}
|
||||||
const chain = "injective";
|
const chain = "Injective";
|
||||||
const { key } = NETWORKS[network][chain];
|
const { key } = NETWORKS[network][chain];
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for Injective`);
|
throw Error(`No ${network} key defined for Injective`);
|
||||||
}
|
}
|
||||||
const { token_bridge } = CONTRACTS[network][chain];
|
const token_bridge = contracts.tokenBridge.get(network, "Injective");
|
||||||
if (token_bridge == undefined) {
|
if (token_bridge == undefined) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
|
throw Error(`Unknown token bridge contract on ${network} for ${chain}`);
|
||||||
}
|
}
|
||||||
|
@ -193,8 +194,8 @@ export async function transferInjective(
|
||||||
token_bridge,
|
token_bridge,
|
||||||
tokenAddress,
|
tokenAddress,
|
||||||
amount,
|
amount,
|
||||||
dstChain,
|
chainToChainId(dstChain),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain)
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain))
|
||||||
);
|
);
|
||||||
|
|
||||||
await signAndSendTx(walletPK, network, msgs);
|
await signAndSendTx(walletPK, network, msgs);
|
||||||
|
@ -268,18 +269,17 @@ export async function queryRegistrationsInjective(
|
||||||
network: Network,
|
network: Network,
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge"
|
module: "Core" | "NFTBridge" | "TokenBridge"
|
||||||
) {
|
) {
|
||||||
const chain = "injective";
|
const chain = "Injective";
|
||||||
const n = NETWORKS[network][chain];
|
const n = NETWORKS[network][chain];
|
||||||
const contracts = CONTRACTS[network][chain];
|
|
||||||
|
|
||||||
let targetContract: string | undefined;
|
let targetContract: string | undefined;
|
||||||
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
targetContract = contracts.token_bridge;
|
targetContract = contracts.tokenBridge.get(network, "Injective");
|
||||||
break;
|
break;
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
targetContract = contracts.nft_bridge;
|
targetContract = contracts.nftBridge.get(network, "Injective");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid module: ${module}`);
|
throw new Error(`Invalid module: ${module}`);
|
||||||
|
@ -297,14 +297,14 @@ export async function queryRegistrationsInjective(
|
||||||
|
|
||||||
// Query the bridge registration for all the chains in parallel.
|
// Query the bridge registration for all the chains in parallel.
|
||||||
const registrations: (any | null)[][] = await Promise.all(
|
const registrations: (any | null)[][] = await Promise.all(
|
||||||
Object.entries(CHAINS)
|
chains
|
||||||
.filter(([cname, _]) => cname !== chain && cname !== "unset")
|
.filter((cname) => cname !== chain)
|
||||||
.map(async ([cname, cid]) => [
|
.map(async (cname) => [
|
||||||
cname,
|
cname,
|
||||||
await (async () => {
|
await (async () => {
|
||||||
let query_msg = {
|
let query_msg = {
|
||||||
chain_registration: {
|
chain_registration: {
|
||||||
chain: cid,
|
chain: chainToChainId(cname),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import {
|
|
||||||
ChainName,
|
|
||||||
CONTRACTS,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import BN from "bn.js";
|
import BN from "bn.js";
|
||||||
import { Account, connect, KeyPair } from "near-api-js";
|
import { Account, connect, KeyPair } from "near-api-js";
|
||||||
import { InMemoryKeyStore } from "near-api-js/lib/key_stores";
|
import { InMemoryKeyStore } from "near-api-js/lib/key_stores";
|
||||||
import { NETWORKS } from "./consts";
|
import { NETWORKS } from "./consts";
|
||||||
import { Network } from "./utils";
|
|
||||||
import { impossible, Payload } from "./vaa";
|
import { impossible, Payload } from "./vaa";
|
||||||
import {
|
import {
|
||||||
transferNearFromNear,
|
transferNearFromNear,
|
||||||
transferTokenFromNear,
|
transferTokenFromNear,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
||||||
import { tryNativeToUint8Array } from "@certusone/wormhole-sdk/lib/esm/utils";
|
import {
|
||||||
|
Chain,
|
||||||
|
chainToChainId,
|
||||||
|
contracts,
|
||||||
|
Network,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { tryNativeToUint8Array } from "./sdk/array";
|
||||||
|
|
||||||
export function keyPairToImplicitAccount(keyPair: KeyPair): string {
|
export function keyPairToImplicitAccount(keyPair: KeyPair): string {
|
||||||
return Buffer.from(keyPair.getPublicKey().data).toString("hex");
|
return Buffer.from(keyPair.getPublicKey().data).toString("hex");
|
||||||
|
@ -23,7 +24,7 @@ export const execute_near = async (
|
||||||
vaa: string,
|
vaa: string,
|
||||||
network: Network
|
network: Network
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const { rpc, key, networkId } = NETWORKS[network].near;
|
const { rpc, key, networkId } = NETWORKS[network].Near;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for NEAR`);
|
throw Error(`No ${network} key defined for NEAR`);
|
||||||
}
|
}
|
||||||
|
@ -32,16 +33,15 @@ export const execute_near = async (
|
||||||
throw Error(`No ${network} rpc defined for NEAR`);
|
throw Error(`No ${network} rpc defined for NEAR`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const contracts = CONTRACTS[network].near;
|
|
||||||
let target_contract: string;
|
let target_contract: string;
|
||||||
let numSubmits = 1;
|
let numSubmits = 1;
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
if (!contracts.core) {
|
const coreContract = contracts.coreBridge(network, "Near");
|
||||||
|
if (!coreContract) {
|
||||||
throw new Error(`Core bridge address not defined for NEAR ${network}`);
|
throw new Error(`Core bridge address not defined for NEAR ${network}`);
|
||||||
}
|
}
|
||||||
|
target_contract = coreContract;
|
||||||
target_contract = contracts.core;
|
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "GuardianSetUpgrade":
|
case "GuardianSetUpgrade":
|
||||||
console.log("Submitting new guardian set");
|
console.log("Submitting new guardian set");
|
||||||
|
@ -57,12 +57,13 @@ export const execute_near = async (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "NFTBridge": {
|
case "NFTBridge": {
|
||||||
if (!contracts.nft_bridge) {
|
const nftContract = contracts.nftBridge.get(network, "Near");
|
||||||
|
if (!nftContract) {
|
||||||
throw new Error(`NFT bridge address not defined for NEAR ${network}`);
|
throw new Error(`NFT bridge address not defined for NEAR ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
numSubmits = 2;
|
numSubmits = 2;
|
||||||
target_contract = contracts.nft_bridge;
|
target_contract = nftContract;
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "ContractUpgrade":
|
case "ContractUpgrade":
|
||||||
console.log("Upgrading contract");
|
console.log("Upgrading contract");
|
||||||
|
@ -82,12 +83,13 @@ export const execute_near = async (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
if (!contracts.token_bridge) {
|
const tbContract = contracts.tokenBridge(network, "Near");
|
||||||
|
if (!tbContract) {
|
||||||
throw new Error(`Token bridge address not defined for NEAR ${network}`);
|
throw new Error(`Token bridge address not defined for NEAR ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
numSubmits = 2;
|
numSubmits = 2;
|
||||||
target_contract = contracts.token_bridge;
|
target_contract = tbContract;
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "ContractUpgrade":
|
case "ContractUpgrade":
|
||||||
console.log("Upgrading contract");
|
console.log("Upgrading contract");
|
||||||
|
@ -158,18 +160,19 @@ export const execute_near = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function transferNear(
|
export async function transferNear(
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
network: Network,
|
network: Network,
|
||||||
rpc: string
|
rpc: string
|
||||||
) {
|
) {
|
||||||
const { key, networkId } = NETWORKS[network].near;
|
const { key, networkId } = NETWORKS[network].Near;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for NEAR`);
|
throw Error(`No ${network} key defined for NEAR`);
|
||||||
}
|
}
|
||||||
const { core, token_bridge } = CONTRACTS[network].near;
|
const core = contracts.coreBridge(network, "Near");
|
||||||
|
const token_bridge = contracts.tokenBridge(network, "Near");
|
||||||
if (core === undefined) {
|
if (core === undefined) {
|
||||||
throw Error(`Unknown core contract on ${network} for NEAR`);
|
throw Error(`Unknown core contract on ${network} for NEAR`);
|
||||||
}
|
}
|
||||||
|
@ -193,8 +196,8 @@ export async function transferNear(
|
||||||
core,
|
core,
|
||||||
token_bridge,
|
token_bridge,
|
||||||
BigInt(amount),
|
BigInt(amount),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain),
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain)),
|
||||||
dstChain,
|
chainToChainId(dstChain),
|
||||||
BigInt(0)
|
BigInt(0)
|
||||||
);
|
);
|
||||||
const result = await nearAccount.functionCall(msg);
|
const result = await nearAccount.functionCall(msg);
|
||||||
|
@ -207,8 +210,8 @@ export async function transferNear(
|
||||||
token_bridge,
|
token_bridge,
|
||||||
tokenAddress,
|
tokenAddress,
|
||||||
BigInt(amount),
|
BigInt(amount),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain),
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain)),
|
||||||
dstChain,
|
chainToChainId(dstChain),
|
||||||
BigInt(0)
|
BigInt(0)
|
||||||
);
|
);
|
||||||
for (const msg of msgs) {
|
for (const msg of msgs) {
|
||||||
|
|
|
@ -0,0 +1,315 @@
|
||||||
|
import { arrayify, zeroPad } from "@ethersproject/bytes";
|
||||||
|
import { PublicKey } from "@solana/web3.js";
|
||||||
|
import {
|
||||||
|
hexValue,
|
||||||
|
hexZeroPad,
|
||||||
|
keccak256,
|
||||||
|
sha256,
|
||||||
|
stripZeros,
|
||||||
|
} from "ethers/lib/utils";
|
||||||
|
import { bech32 } from "bech32";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
ChainId,
|
||||||
|
chainToChainId,
|
||||||
|
chainToPlatform,
|
||||||
|
toChain,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import {
|
||||||
|
PlatformToChains,
|
||||||
|
UniversalAddress,
|
||||||
|
encoding,
|
||||||
|
} from "@wormhole-foundation/sdk";
|
||||||
|
import { isValidSuiAddress } from "@mysten/sui.js";
|
||||||
|
import { sha3_256 } from "js-sha3";
|
||||||
|
import {
|
||||||
|
nativeStringToHexAlgorand,
|
||||||
|
uint8ArrayToNativeStringAlgorand,
|
||||||
|
} from "@certusone/wormhole-sdk/lib/esm/algorand";
|
||||||
|
import { isValidSuiType } from "@certusone/wormhole-sdk/lib/esm/sui";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Returns true iff the hex string represents a native Terra denom.
|
||||||
|
*
|
||||||
|
* Native assets on terra don't have an associated smart contract address, just
|
||||||
|
* like eth isn't an ERC-20 contract on Ethereum.
|
||||||
|
*
|
||||||
|
* The difference is that the EVM implementations of Portal don't support eth
|
||||||
|
* directly, and instead require swapping to an ERC-20 wrapped eth (WETH)
|
||||||
|
* contract first.
|
||||||
|
*
|
||||||
|
* The Terra implementation instead supports Terra-native denoms without
|
||||||
|
* wrapping to CW-20 token first. As these denoms don't have an address, they
|
||||||
|
* are encoded in the Portal payloads by the setting the first byte to 1. This
|
||||||
|
* encoding is safe, because the first 12 bytes of the 32-byte wormhole address
|
||||||
|
* space are not used on Terra otherwise, as cosmos addresses are 20 bytes wide.
|
||||||
|
*/
|
||||||
|
export const isHexNativeTerra = (h: string): boolean => h.startsWith("01");
|
||||||
|
|
||||||
|
const isLikely20ByteCosmwasm = (h: string): boolean =>
|
||||||
|
h.startsWith("000000000000000000000000");
|
||||||
|
|
||||||
|
export const nativeTerraHexToDenom = (h: string): string =>
|
||||||
|
Buffer.from(stripZeros(hexToUint8Array(h.substr(2)))).toString("ascii");
|
||||||
|
|
||||||
|
export const isNativeDenom = (string = "") =>
|
||||||
|
isNativeTerra(string) || string === "uluna";
|
||||||
|
|
||||||
|
export const isNativeTerra = (string = "") =>
|
||||||
|
string.startsWith("u") && string.length === 4;
|
||||||
|
|
||||||
|
export const uint8ArrayToHex = (a: Uint8Array): string =>
|
||||||
|
encoding.hex.encode(a);
|
||||||
|
|
||||||
|
export const hexToUint8Array = (h: string): Uint8Array =>
|
||||||
|
encoding.hex.decode(h);
|
||||||
|
|
||||||
|
export function canonicalAddress(humanAddress: string) {
|
||||||
|
return new Uint8Array(bech32.fromWords(bech32.decode(humanAddress).words));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function humanAddress(hrp: string, canonicalAddress: Uint8Array) {
|
||||||
|
return bech32.encode(hrp, bech32.toWords(canonicalAddress));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildTokenId(
|
||||||
|
chain: Exclude<PlatformToChains<"Cosmwasm">, "Terra">,
|
||||||
|
address: string
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
(isNativeCosmWasmDenom(chain, address) ? "01" : "00") +
|
||||||
|
keccak256(Buffer.from(address, "utf-8")).substring(4)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Convert an address in a wormhole's 32-byte array representation into a chain's
|
||||||
|
* native string representation.
|
||||||
|
*
|
||||||
|
* @throws if address is not the right length for the given chain
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const tryUint8ArrayToNative = (
|
||||||
|
a: Uint8Array,
|
||||||
|
chain: ChainId | Chain
|
||||||
|
): string => {
|
||||||
|
const chainName = toChain(chain);
|
||||||
|
if (chainToPlatform(chainName) === "Evm") {
|
||||||
|
// if (isEVMChain(chainId)) {
|
||||||
|
return hexZeroPad(hexValue(a), 20);
|
||||||
|
} else if (chainToPlatform(chainName) === "Solana") {
|
||||||
|
return new PublicKey(a).toString();
|
||||||
|
} else if (chainName === "Terra" || chainName === "Terra2") {
|
||||||
|
const h = uint8ArrayToHex(a);
|
||||||
|
if (isHexNativeTerra(h)) {
|
||||||
|
return nativeTerraHexToDenom(h);
|
||||||
|
} else {
|
||||||
|
if (chainName === "Terra2" && !isLikely20ByteCosmwasm(h)) {
|
||||||
|
// terra 2 has 32 byte addresses for contracts and 20 for wallets
|
||||||
|
return humanAddress("terra", a);
|
||||||
|
}
|
||||||
|
return humanAddress("terra", a.slice(-20));
|
||||||
|
}
|
||||||
|
} else if (chainName === "Injective") {
|
||||||
|
const h = uint8ArrayToHex(a);
|
||||||
|
return humanAddress("inj", isLikely20ByteCosmwasm(h) ? a.slice(-20) : a);
|
||||||
|
} else if (chainName === "Algorand") {
|
||||||
|
return uint8ArrayToNativeStringAlgorand(a);
|
||||||
|
} else if (chainName == "Wormchain") {
|
||||||
|
const h = uint8ArrayToHex(a);
|
||||||
|
return humanAddress(
|
||||||
|
"wormhole",
|
||||||
|
isLikely20ByteCosmwasm(h) ? a.slice(-20) : a
|
||||||
|
);
|
||||||
|
} else if (chainName === "Xpla") {
|
||||||
|
const h = uint8ArrayToHex(a);
|
||||||
|
return humanAddress("xpla", isLikely20ByteCosmwasm(h) ? a.slice(-20) : a);
|
||||||
|
} else if (chainName === "Sei") {
|
||||||
|
const h = uint8ArrayToHex(a);
|
||||||
|
return humanAddress("sei", isLikely20ByteCosmwasm(h) ? a.slice(-20) : a);
|
||||||
|
} else if (chainName === "Near") {
|
||||||
|
throw Error("uint8ArrayToNative: Use tryHexToNativeStringNear instead.");
|
||||||
|
} else if (chainName === "Osmosis") {
|
||||||
|
throw Error("uint8ArrayToNative: Osmosis not supported yet.");
|
||||||
|
} else if (chainName === "Cosmoshub") {
|
||||||
|
throw Error("uint8ArrayToNative: CosmosHub not supported yet.");
|
||||||
|
} else if (chainName === "Evmos") {
|
||||||
|
throw Error("uint8ArrayToNative: Evmos not supported yet.");
|
||||||
|
} else if (chainName === "Kujira") {
|
||||||
|
throw Error("uint8ArrayToNative: Kujira not supported yet.");
|
||||||
|
} else if (chainName === "Neutron") {
|
||||||
|
throw Error("uint8ArrayToNative: Neutron not supported yet.");
|
||||||
|
} else if (chainName === "Celestia") {
|
||||||
|
throw Error("uint8ArrayToNative: Celestia not supported yet.");
|
||||||
|
} else if (chainName === "Stargaze") {
|
||||||
|
throw Error("uint8ArrayToNative: Stargaze not supported yet.");
|
||||||
|
} else if (chainName === "Seda") {
|
||||||
|
throw Error("uint8ArrayToNative: Seda not supported yet.");
|
||||||
|
} else if (chainName === "Dymension") {
|
||||||
|
throw Error("uint8ArrayToNative: Dymension not supported yet.");
|
||||||
|
} else if (chainName === "Provenance") {
|
||||||
|
throw Error("uint8ArrayToNative: Provenance not supported yet.");
|
||||||
|
} else if (chainName === "Sui") {
|
||||||
|
throw Error("uint8ArrayToNative: Sui not supported yet.");
|
||||||
|
} else if (chainName === "Aptos") {
|
||||||
|
throw Error("uint8ArrayToNative: Aptos not supported yet.");
|
||||||
|
} else if (chainName === "Btc") {
|
||||||
|
throw Error("uint8ArrayToNative: Btc not supported");
|
||||||
|
} else {
|
||||||
|
// This case is never reached
|
||||||
|
// const _: never = chainName;
|
||||||
|
throw Error("Don't know how to convert address for chain " + chainName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Convert an address in a wormhole's 32-byte hex representation into a chain's native
|
||||||
|
* string representation.
|
||||||
|
*
|
||||||
|
* @throws if address is not the right length for the given chain
|
||||||
|
*/
|
||||||
|
export const tryHexToNativeAssetString = (h: string, c: ChainId): string =>
|
||||||
|
c === chainToChainId("Algorand")
|
||||||
|
? // Algorand assets are represented by their asset ids, not an address
|
||||||
|
new UniversalAddress(h).toNative("Algorand").toBigInt().toString()
|
||||||
|
: new UniversalAddress(h).toNative(toChain(c)).toString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Convert an address in a chain's native representation into a 32-byte hex string
|
||||||
|
* understood by wormhole (UniversalAddress).
|
||||||
|
*
|
||||||
|
* @throws if address is a malformed string for the given chain id
|
||||||
|
*/
|
||||||
|
export const tryNativeToHexString = (
|
||||||
|
address: string,
|
||||||
|
chain: ChainId | Chain
|
||||||
|
): string => {
|
||||||
|
const chainName = toChain(chain);
|
||||||
|
if (chainToPlatform(chainName) === "Evm") {
|
||||||
|
return uint8ArrayToHex(zeroPad(arrayify(address), 32));
|
||||||
|
} else if (chainToPlatform(chainName) === "Solana") {
|
||||||
|
return uint8ArrayToHex(zeroPad(new PublicKey(address).toBytes(), 32));
|
||||||
|
} else if (chainName === "Terra") {
|
||||||
|
if (isNativeDenom(address)) {
|
||||||
|
return (
|
||||||
|
"01" +
|
||||||
|
uint8ArrayToHex(
|
||||||
|
zeroPad(new Uint8Array(Buffer.from(address, "ascii")), 31)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return uint8ArrayToHex(zeroPad(canonicalAddress(address), 32));
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
chainName === "Terra2" ||
|
||||||
|
chainName === "Injective" ||
|
||||||
|
chainName === "Xpla" ||
|
||||||
|
chainName === "Sei"
|
||||||
|
) {
|
||||||
|
return buildTokenId(chainName, address);
|
||||||
|
} else if (chainName === "Algorand") {
|
||||||
|
return nativeStringToHexAlgorand(address);
|
||||||
|
} else if (chainName == "Wormchain") {
|
||||||
|
return uint8ArrayToHex(zeroPad(canonicalAddress(address), 32));
|
||||||
|
} else if (chainName === "Near") {
|
||||||
|
return uint8ArrayToHex(arrayify(sha256(Buffer.from(address))));
|
||||||
|
} else if (chainName === "Sui") {
|
||||||
|
if (!isValidSuiType(address) && isValidSuiAddress(address)) {
|
||||||
|
return uint8ArrayToHex(
|
||||||
|
zeroPad(arrayify(address, { allowMissingPrefix: true }), 32)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw Error("nativeToHexString: Sui types not supported yet.");
|
||||||
|
} else if (chainName === "Aptos") {
|
||||||
|
if (isValidAptosType(address)) {
|
||||||
|
return getExternalAddressFromType(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint8ArrayToHex(
|
||||||
|
zeroPad(arrayify(address, { allowMissingPrefix: true }), 32)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// If this case is reached
|
||||||
|
throw Error(`nativeToHexString: ${chainName} not supported yet.`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Convert an address in a chain's native representation into a 32-byte array
|
||||||
|
* understood by wormhole.
|
||||||
|
*
|
||||||
|
* @throws if address is a malformed string for the given chain id
|
||||||
|
*/
|
||||||
|
export function tryNativeToUint8Array(
|
||||||
|
address: string,
|
||||||
|
chain: ChainId | Chain
|
||||||
|
): Uint8Array {
|
||||||
|
const chainId = toChainId(chain);
|
||||||
|
return hexToUint8Array(tryNativeToHexString(address, chainId));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isNativeDenomInjective = (denom: string) => denom === "inj";
|
||||||
|
export const isNativeDenomXpla = (denom: string) => denom === "axpla";
|
||||||
|
export const isNativeDenomSei = (denom: string) => denom === "usei";
|
||||||
|
export const isNativeDenomWormchain = (denom: string) => denom === "uworm";
|
||||||
|
export const isNativeDenomOsmosis = (denom: string) => denom === "uosmo";
|
||||||
|
export const isNativeDenomCosmosHub = (denom: string) => denom === "uatom";
|
||||||
|
export const isNativeDenomEvmos = (denom: string) =>
|
||||||
|
denom === "aevmos" || denom === "atevmos";
|
||||||
|
export const isNativeDenomKujira = (denom: string) => denom === "ukuji";
|
||||||
|
export const isNativeDenomNeutron = (denom: string) => denom === "untrn";
|
||||||
|
export const isNativeDenomCelestia = (denom: string) => denom === "utia";
|
||||||
|
export const isNativeDenomStargaze = (denom: string) => denom === "ustars";
|
||||||
|
export const isNativeDenomSeda = (denom: string) => denom === "aseda";
|
||||||
|
export const isNativeDenomDymension = (denom: string) => denom === "adym";
|
||||||
|
export const isNativeDenomProvenance = (denom: string) => denom === "nhash";
|
||||||
|
|
||||||
|
export function isNativeCosmWasmDenom(
|
||||||
|
chain: PlatformToChains<"Cosmwasm">,
|
||||||
|
address: string
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
((chain === "Terra" || chain === "Terra2") && isNativeDenom(address)) ||
|
||||||
|
(chain === "Injective" && isNativeDenomInjective(address)) ||
|
||||||
|
(chain === "Xpla" && isNativeDenomXpla(address)) ||
|
||||||
|
(chain === "Sei" && isNativeDenomSei(address)) ||
|
||||||
|
(chain === "Wormchain" && isNativeDenomWormchain(address)) ||
|
||||||
|
(chain === "Osmosis" && isNativeDenomOsmosis(address)) ||
|
||||||
|
(chain === "Cosmoshub" && isNativeDenomCosmosHub(address)) ||
|
||||||
|
(chain === "Evmos" && isNativeDenomEvmos(address)) ||
|
||||||
|
(chain === "Kujira" && isNativeDenomKujira(address)) ||
|
||||||
|
(chain === "Neutron" && isNativeDenomNeutron(address)) ||
|
||||||
|
(chain === "Celestia" && isNativeDenomCelestia(address)) ||
|
||||||
|
(chain === "Stargaze" && isNativeDenomStargaze(address)) ||
|
||||||
|
(chain === "Seda" && isNativeDenomSeda(address)) ||
|
||||||
|
(chain === "Dymension" && isNativeDenomDymension(address)) ||
|
||||||
|
(chain === "Provenance" && isNativeDenomProvenance(address))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if given string is a valid fully qualified type of moduleAddress::moduleName::structName.
|
||||||
|
* @param str String to test
|
||||||
|
* @returns Whether or not given string is a valid type
|
||||||
|
*/
|
||||||
|
export const isValidAptosType = (str: string): boolean =>
|
||||||
|
/^(0x)?[0-9a-fA-F]+::\w+::\w+$/.test(str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hashes the given type. Because fully qualified types are a concept unique to Aptos, this
|
||||||
|
* output acts as the address on other chains.
|
||||||
|
* @param fullyQualifiedType Fully qualified type on Aptos
|
||||||
|
* @returns External address corresponding to given type
|
||||||
|
*/
|
||||||
|
export const getExternalAddressFromType = (
|
||||||
|
fullyQualifiedType: string
|
||||||
|
): string => {
|
||||||
|
// hash the type so it fits into 32 bytes
|
||||||
|
return sha3_256(fullyQualifiedType);
|
||||||
|
};
|
|
@ -0,0 +1,130 @@
|
||||||
|
import {
|
||||||
|
JsonRpcProvider,
|
||||||
|
SuiObjectResponse,
|
||||||
|
isValidSuiAddress as isValidFullSuiAddress,
|
||||||
|
normalizeSuiAddress,
|
||||||
|
} from "@mysten/sui.js";
|
||||||
|
import { Chain, chainToChainId } from "@wormhole-foundation/sdk";
|
||||||
|
|
||||||
|
export async function getForeignAssetSui(
|
||||||
|
provider: JsonRpcProvider,
|
||||||
|
tokenBridgeStateObjectId: string,
|
||||||
|
originChain: Chain,
|
||||||
|
originAddress: Uint8Array
|
||||||
|
): Promise<string | null> {
|
||||||
|
const originChainId = chainToChainId(originChain);
|
||||||
|
return getTokenCoinType(
|
||||||
|
provider,
|
||||||
|
tokenBridgeStateObjectId,
|
||||||
|
originAddress,
|
||||||
|
originChainId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getTokenCoinType = async (
|
||||||
|
provider: JsonRpcProvider,
|
||||||
|
tokenBridgeStateObjectId: string,
|
||||||
|
tokenAddress: Uint8Array,
|
||||||
|
tokenChain: number
|
||||||
|
): Promise<string | null> => {
|
||||||
|
const tokenBridgeStateFields = await getObjectFields(
|
||||||
|
provider,
|
||||||
|
tokenBridgeStateObjectId
|
||||||
|
);
|
||||||
|
if (!tokenBridgeStateFields) {
|
||||||
|
throw new Error("Unable to fetch object fields from token bridge state");
|
||||||
|
}
|
||||||
|
|
||||||
|
const coinTypes = tokenBridgeStateFields?.token_registry?.fields?.coin_types;
|
||||||
|
const coinTypesObjectId = coinTypes?.fields?.id?.id;
|
||||||
|
if (!coinTypesObjectId) {
|
||||||
|
throw new Error("Unable to fetch coin types");
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyType = getTableKeyType(coinTypes?.type);
|
||||||
|
if (!keyType) {
|
||||||
|
throw new Error("Unable to get key type");
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await provider.getDynamicFieldObject({
|
||||||
|
parentId: coinTypesObjectId,
|
||||||
|
name: {
|
||||||
|
type: keyType,
|
||||||
|
value: {
|
||||||
|
addr: [...tokenAddress],
|
||||||
|
chain: tokenChain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (response.error) {
|
||||||
|
if (response.error.code === "dynamicFieldNotFound") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
`Unexpected getDynamicFieldObject response ${response.error}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const fields = getFieldsFromObjectResponse(response);
|
||||||
|
return fields?.value ? trimSuiType(ensureHexPrefix(fields.value)) : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getObjectFields = async (
|
||||||
|
provider: JsonRpcProvider,
|
||||||
|
objectId: string
|
||||||
|
): Promise<Record<string, any> | null> => {
|
||||||
|
if (!isValidSuiAddress(objectId)) {
|
||||||
|
throw new Error(`Invalid object ID: ${objectId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await provider.getObject({
|
||||||
|
id: objectId,
|
||||||
|
options: {
|
||||||
|
showContent: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return getFieldsFromObjectResponse(res);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getFieldsFromObjectResponse = (object: SuiObjectResponse) => {
|
||||||
|
const content = object.data?.content;
|
||||||
|
return content && content.dataType === "moveObject" ? content.fields : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ensureHexPrefix(x: string): string {
|
||||||
|
return x.substring(0, 2) !== "0x" ? `0x${x}` : x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method validates any Sui address, even if it's not 32 bytes long, i.e.
|
||||||
|
* "0x2". This differs from Mysten's implementation, which requires that the
|
||||||
|
* given address is 32 bytes long.
|
||||||
|
* @param address Address to check
|
||||||
|
* @returns If given address is a valid Sui address or not
|
||||||
|
*/
|
||||||
|
export const isValidSuiAddress = (address: string): boolean =>
|
||||||
|
isValidFullSuiAddress(normalizeSuiAddress(address));
|
||||||
|
|
||||||
|
export const getTableKeyType = (tableType: string): string | null => {
|
||||||
|
if (!tableType) return null;
|
||||||
|
const match = trimSuiType(tableType).match(/0x2::table::Table<(.*)>/);
|
||||||
|
if (!match) return null;
|
||||||
|
const [keyType] = match[1].split(",");
|
||||||
|
if (!isValidSuiType(keyType)) return null;
|
||||||
|
return keyType;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method removes leading zeroes for types in order to normalize them
|
||||||
|
* since some types returned from the RPC have leading zeroes and others don't.
|
||||||
|
*/
|
||||||
|
export const trimSuiType = (type: string): string =>
|
||||||
|
type.replace(/(0x)(0*)/g, "0x");
|
||||||
|
|
||||||
|
export const isValidSuiType = (type: string): boolean => {
|
||||||
|
const tokens = type.split("::");
|
||||||
|
if (tokens.length !== 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValidSuiAddress(tokens[0]) && !!tokens[1] && !!tokens[2];
|
||||||
|
};
|
|
@ -16,13 +16,6 @@ import {
|
||||||
createUpgradeGuardianSetInstruction,
|
createUpgradeGuardianSetInstruction,
|
||||||
createUpgradeContractInstruction as createWormholeUpgradeContractInstruction,
|
createUpgradeContractInstruction as createWormholeUpgradeContractInstruction,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/solana/wormhole";
|
} from "@certusone/wormhole-sdk/lib/esm/solana/wormhole";
|
||||||
import {
|
|
||||||
CHAINS,
|
|
||||||
CONTRACTS,
|
|
||||||
ChainName,
|
|
||||||
Network,
|
|
||||||
SolanaChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import * as web3s from "@solana/web3.js";
|
import * as web3s from "@solana/web3.js";
|
||||||
import base58 from "bs58";
|
import base58 from "bs58";
|
||||||
import { NETWORKS } from "./consts";
|
import { NETWORKS } from "./consts";
|
||||||
|
@ -32,19 +25,30 @@ import {
|
||||||
transferFromSolana,
|
transferFromSolana,
|
||||||
transferNativeSol,
|
transferNativeSol,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
} from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
||||||
import {
|
|
||||||
hexToUint8Array,
|
|
||||||
tryNativeToUint8Array,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils";
|
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import { getAssociatedTokenAddress } from "@solana/spl-token";
|
import { getAssociatedTokenAddress } from "@solana/spl-token";
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
Network,
|
||||||
|
PlatformToChains,
|
||||||
|
chainToChainId,
|
||||||
|
chainToPlatform,
|
||||||
|
chains,
|
||||||
|
contracts,
|
||||||
|
platformToChains,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { hexToUint8Array, tryNativeToUint8Array } from "./sdk/array";
|
||||||
|
|
||||||
export async function execute_solana(
|
export async function execute_solana(
|
||||||
v: VAA<Payload>,
|
v: VAA<Payload>,
|
||||||
vaa: Buffer,
|
vaa: Buffer,
|
||||||
network: "MAINNET" | "TESTNET" | "DEVNET",
|
network: Network,
|
||||||
chain: SolanaChainName
|
chain: Chain
|
||||||
) {
|
) {
|
||||||
|
if (chainToPlatform(chain) !== "Solana") {
|
||||||
|
// This "Solana" platform, also, includes Pythnet
|
||||||
|
throw new Error("Invalid chain");
|
||||||
|
}
|
||||||
const { rpc, key } = NETWORKS[network][chain];
|
const { rpc, key } = NETWORKS[network][chain];
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for ${chain}`);
|
throw Error(`No ${network} key defined for ${chain}`);
|
||||||
|
@ -57,22 +61,24 @@ export async function execute_solana(
|
||||||
const connection = setupConnection(rpc);
|
const connection = setupConnection(rpc);
|
||||||
const from = web3s.Keypair.fromSecretKey(base58.decode(key));
|
const from = web3s.Keypair.fromSecretKey(base58.decode(key));
|
||||||
|
|
||||||
const contracts = CONTRACTS[network][chain];
|
const coreContract = contracts.coreBridge.get(network, chain);
|
||||||
if (!contracts.core) {
|
if (!coreContract) {
|
||||||
throw new Error(`Core bridge address not defined for ${chain} ${network}`);
|
throw new Error(`Core bridge address not defined for ${chain} ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contracts.nft_bridge) {
|
const nftContract = contracts.nftBridge.get(network, chain);
|
||||||
|
if (!nftContract) {
|
||||||
throw new Error(`NFT bridge address not defined for ${chain} ${network}`);
|
throw new Error(`NFT bridge address not defined for ${chain} ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contracts.token_bridge) {
|
const tbContract = contracts.tokenBridge.get(network, chain);
|
||||||
|
if (!tbContract) {
|
||||||
throw new Error(`Token bridge address not defined for ${chain} ${network}`);
|
throw new Error(`Token bridge address not defined for ${chain} ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bridgeId = new web3s.PublicKey(contracts.core);
|
const bridgeId = new web3s.PublicKey(coreContract);
|
||||||
const tokenBridgeId = new web3s.PublicKey(contracts.token_bridge);
|
const tokenBridgeId = new web3s.PublicKey(tbContract);
|
||||||
const nftBridgeId = new web3s.PublicKey(contracts.nft_bridge);
|
const nftBridgeId = new web3s.PublicKey(nftContract);
|
||||||
|
|
||||||
let ix: web3s.TransactionInstruction;
|
let ix: web3s.TransactionInstruction;
|
||||||
switch (v.payload.module) {
|
switch (v.payload.module) {
|
||||||
|
@ -163,7 +169,7 @@ export async function execute_solana(
|
||||||
break;
|
break;
|
||||||
case "Transfer":
|
case "Transfer":
|
||||||
console.log("Completing transfer");
|
console.log("Completing transfer");
|
||||||
if (payload.tokenChain === CHAINS[chain]) {
|
if (payload.tokenChain === chainToChainId(chain)) {
|
||||||
ix = createCompleteTransferNativeInstruction(
|
ix = createCompleteTransferNativeInstruction(
|
||||||
tokenBridgeId,
|
tokenBridgeId,
|
||||||
bridgeId,
|
bridgeId,
|
||||||
|
@ -228,14 +234,15 @@ export async function execute_solana(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transferSolana(
|
export async function transferSolana(
|
||||||
srcChain: SolanaChainName,
|
srcChain: PlatformToChains<"Solana">,
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
network: Network,
|
network: Network,
|
||||||
rpc: string
|
rpc: string
|
||||||
) {
|
) {
|
||||||
|
platformToChains("Solana");
|
||||||
const { key } = NETWORKS[network][srcChain];
|
const { key } = NETWORKS[network][srcChain];
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for ${srcChain}`);
|
throw Error(`No ${network} key defined for ${srcChain}`);
|
||||||
|
@ -244,12 +251,13 @@ export async function transferSolana(
|
||||||
const connection = setupConnection(rpc);
|
const connection = setupConnection(rpc);
|
||||||
const keypair = web3s.Keypair.fromSecretKey(base58.decode(key));
|
const keypair = web3s.Keypair.fromSecretKey(base58.decode(key));
|
||||||
|
|
||||||
const { core, token_bridge } = CONTRACTS[network][srcChain];
|
const core = contracts.coreBridge.get(network, srcChain);
|
||||||
if (!core) {
|
if (!core) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Core bridge address not defined for ${srcChain} ${network}`
|
`Core bridge address not defined for ${srcChain} ${network}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const token_bridge = contracts.tokenBridge.get(network, srcChain);
|
||||||
if (!token_bridge) {
|
if (!token_bridge) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Token bridge address not defined for ${srcChain} ${network}`
|
`Token bridge address not defined for ${srcChain} ${network}`
|
||||||
|
@ -268,8 +276,8 @@ export async function transferSolana(
|
||||||
tokenBridgeId,
|
tokenBridgeId,
|
||||||
payerAddress,
|
payerAddress,
|
||||||
BigInt(amount),
|
BigInt(amount),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain),
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain)),
|
||||||
dstChain
|
chainToChainId(dstChain)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// find the associated token account
|
// find the associated token account
|
||||||
|
@ -287,8 +295,8 @@ export async function transferSolana(
|
||||||
fromAddress,
|
fromAddress,
|
||||||
tokenAddress, // mintAddress
|
tokenAddress, // mintAddress
|
||||||
BigInt(amount),
|
BigInt(amount),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain),
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain)),
|
||||||
dstChain
|
chainToChainId(dstChain)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,18 +324,17 @@ export async function queryRegistrationsSolana(
|
||||||
network: Network,
|
network: Network,
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge"
|
module: "Core" | "NFTBridge" | "TokenBridge"
|
||||||
): Promise<Object> {
|
): Promise<Object> {
|
||||||
const chain = "solana" as ChainName;
|
const chain = "Solana";
|
||||||
const n = NETWORKS[network][chain];
|
const n = NETWORKS[network][chain];
|
||||||
const contracts = CONTRACTS[network][chain];
|
|
||||||
|
|
||||||
let targetAddress: string | undefined;
|
let targetAddress: string | undefined;
|
||||||
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
targetAddress = contracts.token_bridge;
|
targetAddress = contracts.tokenBridge(network, chain);
|
||||||
break;
|
break;
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
targetAddress = contracts.nft_bridge;
|
targetAddress = contracts.nftBridge(network, chain);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid module: ${module}`);
|
throw new Error(`Invalid module: ${module}`);
|
||||||
|
@ -346,26 +353,26 @@ export async function queryRegistrationsSolana(
|
||||||
|
|
||||||
// Query the bridge registration for all the chains in parallel.
|
// Query the bridge registration for all the chains in parallel.
|
||||||
const registrations: (string | null)[][] = await Promise.all(
|
const registrations: (string | null)[][] = await Promise.all(
|
||||||
Object.entries(CHAINS)
|
chains
|
||||||
.filter(([cname, _]) => cname !== chain && cname !== "unset")
|
.filter((cname) => cname !== chain)
|
||||||
.map(async ([cstr, cid]) => [
|
.map(async (cstr) => [
|
||||||
cstr,
|
cstr,
|
||||||
await (async () => {
|
await (async () => {
|
||||||
let cname = cstr as ChainName;
|
// let cname = cstr as Chain;
|
||||||
let addr: string | undefined;
|
let addr: string | undefined;
|
||||||
if (module === "TokenBridge") {
|
if (module === "TokenBridge") {
|
||||||
addr = CONTRACTS[network][cname].token_bridge;
|
addr = contracts.tokenBridge.get(network, cstr);
|
||||||
} else {
|
} else {
|
||||||
addr = CONTRACTS[network][cname].nft_bridge;
|
addr = contracts.nftBridge.get(network, cstr);
|
||||||
}
|
}
|
||||||
if (addr === undefined) {
|
if (addr === undefined) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let emitter_addr = await getEmitterAddress(cname as ChainName, addr);
|
let emitter_addr = await getEmitterAddress(cstr, addr);
|
||||||
|
|
||||||
const endpoint = deriveEndpointKey(
|
const endpoint = deriveEndpointKey(
|
||||||
programId,
|
programId,
|
||||||
cid,
|
chainToChainId(cstr),
|
||||||
hexToUint8Array(emitter_addr)
|
hexToUint8Array(emitter_addr)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
import {
|
|
||||||
CHAINS,
|
|
||||||
CONTRACTS,
|
|
||||||
ChainName,
|
|
||||||
TerraChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import {
|
import {
|
||||||
Coin,
|
Coin,
|
||||||
Fee,
|
Fee,
|
||||||
|
@ -15,24 +9,29 @@ import {
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { fromUint8Array } from "js-base64";
|
import { fromUint8Array } from "js-base64";
|
||||||
import { NETWORKS } from "./consts";
|
import { NETWORKS } from "./consts";
|
||||||
import { Network } from "./utils";
|
|
||||||
import { Payload, impossible } from "./vaa";
|
import { Payload, impossible } from "./vaa";
|
||||||
import { transferFromTerra } from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
import { transferFromTerra } from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
||||||
import { tryNativeToUint8Array } from "@certusone/wormhole-sdk/lib/esm/utils";
|
import {
|
||||||
|
Chain,
|
||||||
|
Network,
|
||||||
|
chains,
|
||||||
|
contracts,
|
||||||
|
toChainId,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { tryNativeToUint8Array } from "./sdk/array";
|
||||||
|
|
||||||
export async function execute_terra(
|
export async function execute_terra(
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
vaa: Buffer,
|
vaa: Buffer,
|
||||||
network: Network,
|
network: Network,
|
||||||
chain: TerraChainName
|
chain: "Terra" | "Terra2"
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { rpc, key, chain_id } = NETWORKS[network][chain];
|
const { rpc, key, chain_id } = NETWORKS[network][chain];
|
||||||
const contracts = CONTRACTS[network][chain];
|
|
||||||
|
|
||||||
const terra = new LCDClient({
|
const terra = new LCDClient({
|
||||||
URL: rpc,
|
URL: rpc,
|
||||||
chainID: chain_id,
|
chainID: chain_id,
|
||||||
isClassic: chain === "terra",
|
isClassic: chain === "Terra",
|
||||||
});
|
});
|
||||||
|
|
||||||
const wallet = terra.wallet(
|
const wallet = terra.wallet(
|
||||||
|
@ -46,13 +45,14 @@ export async function execute_terra(
|
||||||
|
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
if (!contracts.core) {
|
const coreContract = contracts.coreBridge(network, chain);
|
||||||
|
if (!coreContract) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Core bridge address not defined for ${chain} ${network}`
|
`Core bridge address not defined for ${chain} ${network}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.core;
|
target_contract = coreContract;
|
||||||
// sigh...
|
// sigh...
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_v_a_a: {
|
submit_v_a_a: {
|
||||||
|
@ -75,14 +75,15 @@ export async function execute_terra(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "NFTBridge": {
|
case "NFTBridge": {
|
||||||
if (!contracts.nft_bridge) {
|
const nftContract = contracts.nftBridge.get(network, chain);
|
||||||
|
if (!nftContract) {
|
||||||
// NOTE: this code can safely be removed once the terra NFT bridge is
|
// NOTE: this code can safely be removed once the terra NFT bridge is
|
||||||
// released, but it's fine for it to stay, as the condition will just be
|
// released, but it's fine for it to stay, as the condition will just be
|
||||||
// skipped once 'contracts.nft_bridge' is defined
|
// skipped once 'contracts.nft_bridge' is defined
|
||||||
throw new Error(`NFT bridge not supported yet for ${chain}`);
|
throw new Error(`NFT bridge not supported yet for ${chain}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.nft_bridge;
|
target_contract = nftContract;
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_vaa: {
|
submit_vaa: {
|
||||||
data: fromUint8Array(vaa),
|
data: fromUint8Array(vaa),
|
||||||
|
@ -107,13 +108,14 @@ export async function execute_terra(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
if (!contracts.token_bridge) {
|
const tbContract = contracts.tokenBridge.get(network, chain);
|
||||||
|
if (!tbContract) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Token bridge address not defined for ${chain} ${network}`
|
`Token bridge address not defined for ${chain} ${network}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.token_bridge;
|
target_contract = tbContract;
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_vaa: {
|
submit_vaa: {
|
||||||
data: fromUint8Array(vaa),
|
data: fromUint8Array(vaa),
|
||||||
|
@ -160,8 +162,8 @@ export async function execute_terra(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transferTerra(
|
export async function transferTerra(
|
||||||
srcChain: TerraChainName,
|
srcChain: "Terra" | "Terra2",
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
|
@ -172,7 +174,7 @@ export async function transferTerra(
|
||||||
if (!n.key) {
|
if (!n.key) {
|
||||||
throw Error(`No ${network} key defined for ${srcChain} (see networks.ts)`);
|
throw Error(`No ${network} key defined for ${srcChain} (see networks.ts)`);
|
||||||
}
|
}
|
||||||
const { token_bridge } = CONTRACTS[network][srcChain];
|
const token_bridge = contracts.tokenBridge.get(network, srcChain);
|
||||||
if (!token_bridge) {
|
if (!token_bridge) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for ${srcChain}`);
|
throw Error(`Unknown token bridge contract on ${network} for ${srcChain}`);
|
||||||
}
|
}
|
||||||
|
@ -180,7 +182,7 @@ export async function transferTerra(
|
||||||
const terra = new LCDClient({
|
const terra = new LCDClient({
|
||||||
URL: rpc,
|
URL: rpc,
|
||||||
chainID: n.chain_id,
|
chainID: n.chain_id,
|
||||||
isClassic: srcChain === "terra",
|
isClassic: srcChain === "Terra",
|
||||||
});
|
});
|
||||||
|
|
||||||
const wallet = terra.wallet(
|
const wallet = terra.wallet(
|
||||||
|
@ -194,8 +196,8 @@ export async function transferTerra(
|
||||||
token_bridge,
|
token_bridge,
|
||||||
tokenAddress,
|
tokenAddress,
|
||||||
amount,
|
amount,
|
||||||
dstChain,
|
toChainId(dstChain),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain)
|
tryNativeToUint8Array(dstAddress, toChainId(dstChain))
|
||||||
);
|
);
|
||||||
await signAndSendTx(terra, wallet, msgs);
|
await signAndSendTx(terra, wallet, msgs);
|
||||||
}
|
}
|
||||||
|
@ -242,20 +244,19 @@ async function signAndSendTx(
|
||||||
|
|
||||||
export async function queryRegistrationsTerra(
|
export async function queryRegistrationsTerra(
|
||||||
network: Network,
|
network: Network,
|
||||||
chain: TerraChainName,
|
chain: "Terra" | "Terra2",
|
||||||
module: "Core" | "NFTBridge" | "TokenBridge"
|
module: "Core" | "NFTBridge" | "TokenBridge"
|
||||||
): Promise<Object> {
|
): Promise<Object> {
|
||||||
const n = NETWORKS[network][chain];
|
const n = NETWORKS[network][chain];
|
||||||
const contracts = CONTRACTS[network][chain];
|
|
||||||
|
|
||||||
let targetContract: string | undefined;
|
let targetContract: string | undefined;
|
||||||
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
targetContract = contracts.token_bridge;
|
targetContract = contracts.tokenBridge(network, chain);
|
||||||
break;
|
break;
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
targetContract = contracts.nft_bridge;
|
targetContract = contracts.nftBridge.get(network, chain);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid module: ${module}`);
|
throw new Error(`Invalid module: ${module}`);
|
||||||
|
@ -276,19 +277,19 @@ export async function queryRegistrationsTerra(
|
||||||
const client = new LCDClient({
|
const client = new LCDClient({
|
||||||
URL: n.rpc,
|
URL: n.rpc,
|
||||||
chainID: n.chain_id,
|
chainID: n.chain_id,
|
||||||
isClassic: chain === "terra",
|
isClassic: chain === "Terra",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Query the bridge registration for all the chains in parallel.
|
// Query the bridge registration for all the chains in parallel.
|
||||||
const registrations: (string | null)[][] = await Promise.all(
|
const registrations: (string | null)[][] = await Promise.all(
|
||||||
Object.entries(CHAINS)
|
chains
|
||||||
.filter(([cname, _]) => cname !== chain && cname !== "unset")
|
.filter((cname) => cname !== chain)
|
||||||
.map(async ([cname, cid]) => [
|
.map(async (cname) => [
|
||||||
cname,
|
cname,
|
||||||
await (async () => {
|
await (async () => {
|
||||||
let query_msg = {
|
let query_msg = {
|
||||||
chain_registration: {
|
chain_registration: {
|
||||||
chain: cid,
|
chain: toChainId(cname),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
// > paul@W7windows:~$ worm evm info -n mainnet -c ethereum -m TokenBridge
|
||||||
|
// {
|
||||||
|
// "address": "0x3ee18B2214AFF97000D974cf647E7C347E8fa585",
|
||||||
|
// "wormhole": "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B",
|
||||||
|
// "implementation": "0x381752f5458282d317d12C30D2Bd4D6E1FD8841e",
|
||||||
|
// "isInitialized": true,
|
||||||
|
// "tokenImplementation": "0x0fD04a68d3c3A692d6Fa30384D1A87Ef93554eE6",
|
||||||
|
// "chainId": 2,
|
||||||
|
// "finality": 1,
|
||||||
|
// "evmChainId": "1",
|
||||||
|
// "isFork": false,
|
||||||
|
// "governanceChainId": 1,
|
||||||
|
// "governanceContract": "0x0000000000000000000000000000000000000000000000000000000000000004",
|
||||||
|
// "WETH": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
||||||
|
// "registrations": {
|
||||||
|
// "solana": "0xec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5",
|
||||||
|
// "terra": "0x0000000000000000000000007cf7b764e38a0a5e967972c1df77d432510564e2",
|
||||||
|
// "bsc": "0x000000000000000000000000b6f6d86a8f9879a9c87f643768d9efc38c1da6e7",
|
||||||
|
// "polygon": "0x0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde",
|
||||||
|
// "avalanche": "0x0000000000000000000000000e082f06ff657d94310cb8ce8b0d9a04541d8052",
|
||||||
|
// "oasis": "0x0000000000000000000000005848c791e09901b40a9ef749f2a6735b418d7564",
|
||||||
|
// "algorand": "0x67e93fa6c8ac5c819990aa7340c0c16b508abb1178be9b30d024b8ac25193d45",
|
||||||
|
// "aurora": "0x00000000000000000000000051b5123a7b0f9b2ba265f9c4c8de7d78d52f510f",
|
||||||
|
// "fantom": "0x0000000000000000000000007c9fc5741288cdfdd83ceb07f3ea7e22618d79d2",
|
||||||
|
// "karura": "0x000000000000000000000000ae9d7fe007b3327aa64a32824aaac52c42a6e624",
|
||||||
|
// "acala": "0x000000000000000000000000ae9d7fe007b3327aa64a32824aaac52c42a6e624",
|
||||||
|
// "klaytn": "0x0000000000000000000000005b08ac39eaed75c0439fc750d9fe7e1f9dd0193f",
|
||||||
|
// "celo": "0x000000000000000000000000796dff6d74f3e27060b71255fe517bfb23c93eed",
|
||||||
|
// "near": "0x148410499d3fcda4dcfd68a1ebfcdddda16ab28326448d4aae4d2f0465cdfcb7",
|
||||||
|
// "moonbeam": "0x000000000000000000000000b1731c586ca89a23809861c6103f0b96b3f57d92",
|
||||||
|
// "neon": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "terra2": "0xa463ad028fb79679cfc8ce1efba35ac0e77b35080a1abe9bebe83461f176b0a3",
|
||||||
|
// "injective": "0x00000000000000000000000045dbea4617971d93188eda21530bc6503d153313",
|
||||||
|
// "osmosis": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "sui": "0xccceeb29348f71bdd22ffef43a2a19c1f5b5e17c5cca5411529120182672ade5",
|
||||||
|
// "aptos": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
// "arbitrum": "0x0000000000000000000000000b2402144bb366a632d14b83f244d2e0e21bd39c",
|
||||||
|
// "optimism": "0x0000000000000000000000001d68124e65fafc907325e3edbf8c4d84499daa8b",
|
||||||
|
// "gnosis": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "pythnet": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "xpla": "0x8f9cf727175353b17a5f574270e370776123d90fd74956ae4277962b4fdee24c",
|
||||||
|
// "btc": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "base": "0x0000000000000000000000008d2de8d2f73f1f4cab472ac9a881c9b123c79627",
|
||||||
|
// "sei": "0x86c5fd957e2db8389553e1728f9c27964b22a8154091ccba54d75f4b10c61f5e",
|
||||||
|
// "rootstock": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "scroll": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d",
|
||||||
|
// "mantle": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "blast": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d",
|
||||||
|
// "xlayer": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "linea": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "berachain": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "seievm": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "wormchain": "0xaeb534c45c3049d380b9d9b966f9895f53abd4301bfaff407fa09dea8ae7a924",
|
||||||
|
// "cosmoshub": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "evmos": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "kujira": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "neutron": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "celestia": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "stargaze": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "seda": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "dymension": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "provenance": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "sepolia": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "arbitrum_sepolia": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "base_sepolia": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "optimism_sepolia": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "holesky": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
// "polygon_sepolia": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// >>>worm info registrations mainnet ethereum TokenBridge -v
|
||||||
|
// Verification of ethereum MAINNET succeeded!
|
||||||
|
|
||||||
|
// >>>paul@W7windows:~$ worm info contract mainnet ethereum TokenBridge
|
||||||
|
// 0x3ee18B2214AFF97000D974cf647E7C347E8fa585
|
|
@ -1,14 +1,14 @@
|
||||||
|
import {
|
||||||
|
Chain,
|
||||||
|
ChainId,
|
||||||
|
Network,
|
||||||
|
PlatformToChains,
|
||||||
|
chainToPlatform,
|
||||||
|
toChain,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
import { spawnSync } from "child_process";
|
import { spawnSync } from "child_process";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
|
|
||||||
export type Network = "MAINNET" | "TESTNET" | "DEVNET";
|
|
||||||
|
|
||||||
export function assertNetwork(n: string): asserts n is Network {
|
|
||||||
if (n !== "MAINNET" && n !== "TESTNET" && n !== "DEVNET") {
|
|
||||||
throw Error(`Unknown network: ${n}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const checkBinary = (binaryName: string, readmeUrl?: string): void => {
|
export const checkBinary = (binaryName: string, readmeUrl?: string): void => {
|
||||||
const binary = spawnSync(binaryName, ["--version"]);
|
const binary = spawnSync(binaryName, ["--version"]);
|
||||||
if (binary.status !== 0) {
|
if (binary.status !== 0) {
|
||||||
|
@ -29,3 +29,33 @@ export const evm_address = (x: string): string => {
|
||||||
export const hex = (x: string): string => {
|
export const hex = (x: string): string => {
|
||||||
return ethers.utils.hexlify(x, { allowMissingPrefix: true });
|
return ethers.utils.hexlify(x, { allowMissingPrefix: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function assertEVMChain(
|
||||||
|
chain: ChainId | Chain
|
||||||
|
): asserts chain is PlatformToChains<"Evm"> {
|
||||||
|
if (chainToPlatform(toChain(chain)) !== "Evm") {
|
||||||
|
throw Error(`Expected an EVM chain, but ${chain} is not`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNetwork(network: string): Network {
|
||||||
|
const lcNetwork: string = network.toLowerCase();
|
||||||
|
if (lcNetwork === "mainnet") {
|
||||||
|
return "Mainnet";
|
||||||
|
}
|
||||||
|
if (lcNetwork === "testnet") {
|
||||||
|
return "Testnet";
|
||||||
|
}
|
||||||
|
if (lcNetwork === "devnet") {
|
||||||
|
return "Devnet";
|
||||||
|
}
|
||||||
|
throw new Error(`Unknown network: ${network}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function chainToChain(input: string): Chain {
|
||||||
|
if (input.length < 2) {
|
||||||
|
throw new Error(`Invalid chain: ${input}`);
|
||||||
|
}
|
||||||
|
const chainStr = input[0].toUpperCase() + input.slice(1).toLowerCase();
|
||||||
|
return toChain(chainStr);
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
import {
|
|
||||||
CONTRACTS,
|
|
||||||
ChainName,
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
|
||||||
import {
|
import {
|
||||||
Coin,
|
Coin,
|
||||||
Fee,
|
Fee,
|
||||||
|
@ -12,18 +8,22 @@ import {
|
||||||
} from "@xpla/xpla.js";
|
} from "@xpla/xpla.js";
|
||||||
import { fromUint8Array } from "js-base64";
|
import { fromUint8Array } from "js-base64";
|
||||||
import { NETWORKS } from "./consts";
|
import { NETWORKS } from "./consts";
|
||||||
import { Network } from "./utils";
|
|
||||||
import { Payload, impossible } from "./vaa";
|
import { Payload, impossible } from "./vaa";
|
||||||
import { transferFromXpla } from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
import { transferFromXpla } from "@certusone/wormhole-sdk/lib/esm/token_bridge/transfer";
|
||||||
import { tryNativeToUint8Array } from "@certusone/wormhole-sdk/lib/esm/utils";
|
import {
|
||||||
|
Chain,
|
||||||
|
chainToChainId,
|
||||||
|
contracts,
|
||||||
|
Network,
|
||||||
|
} from "@wormhole-foundation/sdk-base";
|
||||||
|
import { tryNativeToUint8Array } from "./sdk/array";
|
||||||
|
|
||||||
export async function execute_xpla(
|
export async function execute_xpla(
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
vaa: Buffer,
|
vaa: Buffer,
|
||||||
network: Network
|
network: Network
|
||||||
) {
|
) {
|
||||||
const { rpc, key, chain_id } = NETWORKS[network].xpla;
|
const { rpc, key, chain_id } = NETWORKS[network].Xpla;
|
||||||
const contracts = CONTRACTS[network].xpla;
|
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for XPLA`);
|
throw Error(`No ${network} key defined for XPLA`);
|
||||||
}
|
}
|
||||||
|
@ -47,11 +47,12 @@ export async function execute_xpla(
|
||||||
let execute_msg: object;
|
let execute_msg: object;
|
||||||
switch (payload.module) {
|
switch (payload.module) {
|
||||||
case "Core": {
|
case "Core": {
|
||||||
if (!contracts.core) {
|
const coreContract = contracts.coreBridge.get(network, "Xpla");
|
||||||
|
if (!coreContract) {
|
||||||
throw new Error(`Core bridge address not defined for XPLA ${network}`);
|
throw new Error(`Core bridge address not defined for XPLA ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.core;
|
target_contract = coreContract;
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_v_a_a: {
|
submit_v_a_a: {
|
||||||
vaa: fromUint8Array(vaa),
|
vaa: fromUint8Array(vaa),
|
||||||
|
@ -73,14 +74,15 @@ export async function execute_xpla(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "NFTBridge": {
|
case "NFTBridge": {
|
||||||
if (!contracts.nft_bridge) {
|
const nftContract = contracts.nftBridge.get(network, "Xpla");
|
||||||
|
if (!nftContract) {
|
||||||
// NOTE: this code can safely be removed once the terra NFT bridge is
|
// NOTE: this code can safely be removed once the terra NFT bridge is
|
||||||
// released, but it's fine for it to stay, as the condition will just be
|
// released, but it's fine for it to stay, as the condition will just be
|
||||||
// skipped once 'contracts.nft_bridge' is defined
|
// skipped once 'contracts.nft_bridge' is defined
|
||||||
throw new Error("NFT bridge not supported yet for XPLA");
|
throw new Error("NFT bridge not supported yet for XPLA");
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.nft_bridge;
|
target_contract = nftContract;
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_vaa: {
|
submit_vaa: {
|
||||||
data: fromUint8Array(vaa),
|
data: fromUint8Array(vaa),
|
||||||
|
@ -105,11 +107,12 @@ export async function execute_xpla(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "TokenBridge": {
|
case "TokenBridge": {
|
||||||
if (!contracts.token_bridge) {
|
const tbContract = contracts.tokenBridge.get(network, "Xpla");
|
||||||
|
if (!tbContract) {
|
||||||
throw new Error(`Token bridge address not defined for XPLA ${network}`);
|
throw new Error(`Token bridge address not defined for XPLA ${network}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_contract = contracts.token_bridge;
|
target_contract = tbContract;
|
||||||
execute_msg = {
|
execute_msg = {
|
||||||
submit_vaa: {
|
submit_vaa: {
|
||||||
data: fromUint8Array(vaa),
|
data: fromUint8Array(vaa),
|
||||||
|
@ -156,18 +159,18 @@ export async function execute_xpla(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transferXpla(
|
export async function transferXpla(
|
||||||
dstChain: ChainName,
|
dstChain: Chain,
|
||||||
dstAddress: string,
|
dstAddress: string,
|
||||||
tokenAddress: string,
|
tokenAddress: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
network: Network,
|
network: Network,
|
||||||
rpc: string
|
rpc: string
|
||||||
) {
|
) {
|
||||||
const { key, chain_id } = NETWORKS[network].xpla;
|
const { key, chain_id } = NETWORKS[network].Xpla;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
throw Error(`No ${network} key defined for XPLA`);
|
throw Error(`No ${network} key defined for XPLA`);
|
||||||
}
|
}
|
||||||
const { token_bridge } = CONTRACTS[network].xpla;
|
const token_bridge = contracts.tokenBridge.get(network, "Xpla");
|
||||||
if (token_bridge == undefined) {
|
if (token_bridge == undefined) {
|
||||||
throw Error(`Unknown token bridge contract on ${network} for XPLA`);
|
throw Error(`Unknown token bridge contract on ${network} for XPLA`);
|
||||||
}
|
}
|
||||||
|
@ -185,8 +188,8 @@ export async function transferXpla(
|
||||||
token_bridge,
|
token_bridge,
|
||||||
tokenAddress,
|
tokenAddress,
|
||||||
amount,
|
amount,
|
||||||
dstChain,
|
chainToChainId(dstChain),
|
||||||
tryNativeToUint8Array(dstAddress, dstChain)
|
tryNativeToUint8Array(dstAddress, chainToChainId(dstChain))
|
||||||
);
|
);
|
||||||
await signAndSendTx(client, wallet, msgs);
|
await signAndSendTx(client, wallet, msgs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"strict": true
|
"strict": true
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue