clients/js: minified bundle

This commit is contained in:
Evan Gray 2023-05-05 10:02:22 -04:00 committed by Evan Gray
parent b4a5bc8aef
commit dfe4baf1b1
61 changed files with 1395 additions and 870 deletions

View File

@ -1,5 +1,11 @@
# Changelog # Changelog
## 0.0.3
### Changed
Build a minified bundle
## 0.0.2 ## 0.0.2
### Changed ### Changed

View File

@ -24,6 +24,7 @@ install: build
test: build test: build
# This first invocation will set up the initial config, so that the warning # This first invocation will set up the initial config, so that the warning
# doesn't show up in the tests # doesn't show up in the tests
npm run check
node build/main.js --version > /dev/null node build/main.js --version > /dev/null
./run_parse_tests ./run_parse_tests

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "@wormhole-foundation/wormhole-cli", "name": "@wormhole-foundation/wormhole-cli",
"version": "0.0.2", "version": "0.0.3",
"description": "CLI for Wormhole related activities", "description": "CLI for Wormhole related activities",
"homepage": "https://wormhole.com", "homepage": "https://wormhole.com",
"bin": { "bin": {
@ -11,8 +11,10 @@
], ],
"repository": "https://github.com/certusone/wormhole/tree/main/clients/js", "repository": "https://github.com/certusone/wormhole/tree/main/clients/js",
"scripts": { "scripts": {
"start": "ts-node main.ts", "start": "npm run build && node ./build/main.js",
"build": "tsc", "build": "esbuild src/main.ts --bundle --outfile=build/main.js --minify --platform=node --target=node16",
"check": "tsc --noEmit",
"prepublishOnly": "npm run check",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"author": "Wormhole Contributors", "author": "Wormhole Contributors",
@ -24,7 +26,7 @@
], ],
"dependencies": { "dependencies": {
"@celo-tools/celo-ethers-wrapper": "^0.1.0", "@celo-tools/celo-ethers-wrapper": "^0.1.0",
"@certusone/wormhole-sdk": "^0.9.15-beta.4", "@certusone/wormhole-sdk": "^0.9.16",
"@cosmjs/encoding": "^0.26.2", "@cosmjs/encoding": "^0.26.2",
"@injectivelabs/networks": "^1.10.7", "@injectivelabs/networks": "^1.10.7",
"@injectivelabs/sdk-ts": "^1.10.47", "@injectivelabs/sdk-ts": "^1.10.47",
@ -45,11 +47,12 @@
"buffer-layout": "^1.2.2", "buffer-layout": "^1.2.2",
"config": "^3.3.7", "config": "^3.3.7",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"esbuild": "0.17.18",
"ethers": "^5.6.8", "ethers": "^5.6.8",
"js-base64": "^3.6.1", "js-base64": "^3.6.1",
"near-api-js": "^0.45.1", "near-api-js": "^0.45.1",
"near-seed-phrase": "^0.2.0", "near-seed-phrase": "^0.2.0",
"yargs": "^17.0.1" "yargs": "^17.7.2"
}, },
"devDependencies": { "devDependencies": {
"@truffle/hdwallet-provider": "^2.0.15", "@truffle/hdwallet-provider": "^2.0.15",
@ -57,7 +60,6 @@
"@types/bs58": "^4.0.1", "@types/bs58": "^4.0.1",
"@types/yargs": "^17.0.2", "@types/yargs": "^17.0.2",
"copy-dir": "^1.3.0", "copy-dir": "^1.3.0",
"ts-node": "^10.7.0",
"typescript": "^4.6" "typescript": "^4.6"
} }
} }

View File

@ -4,8 +4,8 @@ import { Account, Algodv2, mnemonicToSecretKey } from "algosdk";
import { import {
signSendAndConfirmAlgorand, signSendAndConfirmAlgorand,
_submitVAAAlgorand, _submitVAAAlgorand,
} from "@certusone/wormhole-sdk/lib/cjs/algorand"; } from "@certusone/wormhole-sdk/lib/esm/algorand";
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
export async function execute_algorand( export async function execute_algorand(
payload: Payload, payload: Payload,
@ -46,7 +46,7 @@ export async function execute_algorand(
console.log("Upgrading core contract"); console.log("Upgrading core contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on algorand") throw new Error("RecoverChainId not supported on algorand");
default: default:
impossible(payload); impossible(payload);
} }
@ -64,7 +64,7 @@ export async function execute_algorand(
console.log("Upgrading contract"); console.log("Upgrading contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on algorand") throw new Error("RecoverChainId not supported on algorand");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
break; break;
@ -85,7 +85,7 @@ export async function execute_algorand(
console.log("Upgrading contract"); console.log("Upgrading contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on algorand") throw new Error("RecoverChainId not supported on algorand");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
break; break;

View File

@ -3,7 +3,11 @@ import { NETWORKS } from "./networks";
import { impossible, Payload } from "./vaa"; import { impossible, Payload } from "./vaa";
import { sha3_256 } from "js-sha3"; import { sha3_256 } from "js-sha3";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { assertChain, ChainId, CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import {
assertChain,
ChainId,
CONTRACTS,
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
export async function execute_aptos( export async function execute_aptos(
payload: Payload, payload: Payload,
@ -23,66 +27,115 @@ export async function execute_aptos(
case "Core": case "Core":
contract = contract ?? CONTRACTS[network][chain]["core"]; contract = contract ?? CONTRACTS[network][chain]["core"];
if (contract === undefined) { if (contract === undefined) {
throw Error("core bridge contract is undefined") throw Error("core bridge contract is undefined");
} }
switch (payload.type) { switch (payload.type) {
case "GuardianSetUpgrade": case "GuardianSetUpgrade":
console.log("Submitting new guardian set") console.log("Submitting new guardian set");
await callEntryFunc(network, rpc, `${contract}::guardian_set_upgrade`, "submit_vaa_entry", [], [bcsVAA]); await callEntryFunc(
break network,
rpc,
`${contract}::guardian_set_upgrade`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "ContractUpgrade": case "ContractUpgrade":
console.log("Upgrading core contract") console.log("Upgrading core contract");
await callEntryFunc(network, rpc, `${contract}::contract_upgrade`, "submit_vaa_entry", [], [bcsVAA]); await callEntryFunc(
break network,
rpc,
`${contract}::contract_upgrade`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on aptos") throw new Error("RecoverChainId not supported on aptos");
default: default:
impossible(payload) impossible(payload);
} }
break break;
case "NFTBridge": case "NFTBridge":
contract = contract ?? CONTRACTS[network][chain]["nft_bridge"]; contract = contract ?? CONTRACTS[network][chain]["nft_bridge"];
if (contract === undefined) { if (contract === undefined) {
throw Error("nft bridge contract is undefined") throw Error("nft bridge contract is undefined");
} }
switch (payload.type) { switch (payload.type) {
case "ContractUpgrade": case "ContractUpgrade":
console.log("Upgrading contract") console.log("Upgrading contract");
await callEntryFunc(network, rpc, `${contract}::contract_upgrade`, "submit_vaa_entry", [], [bcsVAA]); await callEntryFunc(
break network,
rpc,
`${contract}::contract_upgrade`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on aptos") throw new Error("RecoverChainId not supported on aptos");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain") console.log("Registering chain");
await callEntryFunc(network, rpc, `${contract}::register_chain`, "submit_vaa_entry", [], [bcsVAA]); await callEntryFunc(
break network,
rpc,
`${contract}::register_chain`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "Transfer": { case "Transfer": {
console.log("Completing transfer") console.log("Completing transfer");
await callEntryFunc(network, rpc, `${contract}::complete_transfer`, "submit_vaa_entry", [], [bcsVAA]); await callEntryFunc(
break network,
rpc,
`${contract}::complete_transfer`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
} }
default: default:
impossible(payload) impossible(payload);
} }
break break;
case "TokenBridge": case "TokenBridge":
contract = contract ?? CONTRACTS[network][chain]["token_bridge"]; contract = contract ?? CONTRACTS[network][chain]["token_bridge"];
if (contract === undefined) { if (contract === undefined) {
throw Error("token bridge contract is undefined") throw Error("token bridge contract is undefined");
} }
switch (payload.type) { switch (payload.type) {
case "ContractUpgrade": case "ContractUpgrade":
console.log("Upgrading contract") console.log("Upgrading contract");
await callEntryFunc(network, rpc, `${contract}::contract_upgrade`, "submit_vaa_entry", [], [bcsVAA]); await callEntryFunc(
break network,
rpc,
`${contract}::contract_upgrade`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on aptos") throw new Error("RecoverChainId not supported on aptos");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain") console.log("Registering chain");
await callEntryFunc(network, rpc, `${contract}::register_chain`, "submit_vaa_entry", [], [bcsVAA]); await callEntryFunc(
break network,
rpc,
`${contract}::register_chain`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "AttestMeta": { case "AttestMeta": {
console.log("Creating wrapped token") console.log("Creating wrapped token");
// Deploying a wrapped asset requires two transactions: // Deploying a wrapped asset requires two transactions:
// 1. Publish a new module under a resource account that defines a type T // 1. Publish a new module under a resource account that defines a type T
// 2. Initialise a new coin with that type T // 2. Initialise a new coin with that type T
@ -91,9 +144,16 @@ export async function execute_aptos(
// //
// Tx 1. // Tx 1.
try { try {
await callEntryFunc(network, rpc, `${contract}::wrapped`, "create_wrapped_coin_type", [], [bcsVAA]); await callEntryFunc(
network,
rpc,
`${contract}::wrapped`,
"create_wrapped_coin_type",
[],
[bcsVAA]
);
} catch (e) { } catch (e) {
console.log("this one already happened (probably)") console.log("this one already happened (probably)");
} }
// We just deployed the module (notice the "wait" argument which makes // We just deployed the module (notice the "wait" argument which makes
@ -105,63 +165,102 @@ export async function execute_aptos(
const tokenAddress = payload.tokenAddress; const tokenAddress = payload.tokenAddress;
const tokenChain = payload.tokenChain; const tokenChain = payload.tokenChain;
assertChain(tokenChain); assertChain(tokenChain);
let wrappedContract = deriveWrappedAssetAddress(hex(contract), tokenChain, hex(tokenAddress)); let wrappedContract = deriveWrappedAssetAddress(
hex(contract),
tokenChain,
hex(tokenAddress)
);
// Tx 2. // Tx 2.
console.log(`Deploying resource account ${wrappedContract}`); console.log(`Deploying resource account ${wrappedContract}`);
let token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString(`${wrappedContract}::coin::T`)); let token = new TxnBuilderTypes.TypeTagStruct(
await callEntryFunc(network, rpc, `${contract}::wrapped`, "create_wrapped_coin", [token], [bcsVAA]); TxnBuilderTypes.StructTag.fromString(`${wrappedContract}::coin::T`)
);
await callEntryFunc(
network,
rpc,
`${contract}::wrapped`,
"create_wrapped_coin",
[token],
[bcsVAA]
);
break break;
} }
case "Transfer": { case "Transfer": {
console.log("Completing transfer") console.log("Completing transfer");
// 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); assertChain(tokenChain);
let wrappedContract = deriveWrappedAssetAddress(hex(contract), tokenChain, hex(tokenAddress)); let wrappedContract = deriveWrappedAssetAddress(
const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString(`${wrappedContract}::coin::T`)); hex(contract),
await callEntryFunc(network, rpc, `${contract}::complete_transfer`, "submit_vaa_and_register_entry", [token], [bcsVAA]); tokenChain,
break hex(tokenAddress)
);
const token = new TxnBuilderTypes.TypeTagStruct(
TxnBuilderTypes.StructTag.fromString(`${wrappedContract}::coin::T`)
);
await callEntryFunc(
network,
rpc,
`${contract}::complete_transfer`,
"submit_vaa_and_register_entry",
[token],
[bcsVAA]
);
break;
} }
case "TransferWithPayload": case "TransferWithPayload":
throw Error("Can't complete payload 3 transfer from CLI") throw Error("Can't complete payload 3 transfer from CLI");
default: default:
impossible(payload) impossible(payload);
break break;
} }
break break;
default: default:
impossible(payload) impossible(payload);
} }
} }
export function deriveWrappedAssetAddress( export function deriveWrappedAssetAddress(
token_bridge_address: Uint8Array, // 32 bytes token_bridge_address: Uint8Array, // 32 bytes
origin_chain: ChainId, origin_chain: ChainId,
origin_address: Uint8Array, // 32 bytes origin_address: Uint8Array // 32 bytes
): string { ): string {
let chain: Buffer = Buffer.alloc(2); let chain: Buffer = Buffer.alloc(2);
chain.writeUInt16BE(origin_chain); chain.writeUInt16BE(origin_chain);
if (origin_address.length != 32) { if (origin_address.length != 32) {
throw new Error(`${origin_address}`) throw new Error(`${origin_address}`);
} }
// from https://github.com/aptos-labs/aptos-core/blob/25696fd266498d81d346fe86e01c330705a71465/aptos-move/framework/aptos-framework/sources/account.move#L90-L95 // from https://github.com/aptos-labs/aptos-core/blob/25696fd266498d81d346fe86e01c330705a71465/aptos-move/framework/aptos-framework/sources/account.move#L90-L95
let DERIVE_RESOURCE_ACCOUNT_SCHEME = Buffer.alloc(1); let DERIVE_RESOURCE_ACCOUNT_SCHEME = Buffer.alloc(1);
DERIVE_RESOURCE_ACCOUNT_SCHEME.writeUInt8(255); DERIVE_RESOURCE_ACCOUNT_SCHEME.writeUInt8(255);
return sha3_256(Buffer.concat([token_bridge_address, chain, Buffer.from("::", "ascii"), origin_address, DERIVE_RESOURCE_ACCOUNT_SCHEME])); return sha3_256(
Buffer.concat([
token_bridge_address,
chain,
Buffer.from("::", "ascii"),
origin_address,
DERIVE_RESOURCE_ACCOUNT_SCHEME,
])
);
} }
export function deriveResourceAccount( export function deriveResourceAccount(
deployer: Uint8Array, // 32 bytes deployer: Uint8Array, // 32 bytes
seed: string, seed: string
) { ) {
// from https://github.com/aptos-labs/aptos-core/blob/25696fd266498d81d346fe86e01c330705a71465/aptos-move/framework/aptos-framework/sources/account.move#L90-L95 // from https://github.com/aptos-labs/aptos-core/blob/25696fd266498d81d346fe86e01c330705a71465/aptos-move/framework/aptos-framework/sources/account.move#L90-L95
let DERIVE_RESOURCE_ACCOUNT_SCHEME = Buffer.alloc(1); let DERIVE_RESOURCE_ACCOUNT_SCHEME = Buffer.alloc(1);
DERIVE_RESOURCE_ACCOUNT_SCHEME.writeUInt8(255); DERIVE_RESOURCE_ACCOUNT_SCHEME.writeUInt8(255);
return sha3_256(Buffer.concat([deployer, Buffer.from(seed, "ascii"), DERIVE_RESOURCE_ACCOUNT_SCHEME])) return sha3_256(
Buffer.concat([
deployer,
Buffer.from(seed, "ascii"),
DERIVE_RESOURCE_ACCOUNT_SCHEME,
])
);
} }
export async function callEntryFunc( export async function callEntryFunc(
@ -170,7 +269,7 @@ export async function callEntryFunc(
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>
) { ) {
let key: string | undefined = NETWORKS[network]["aptos"].key; let key: string | undefined = NETWORKS[network]["aptos"].key;
if (key === undefined) { if (key === undefined) {
@ -179,7 +278,7 @@ export async function callEntryFunc(
const accountFrom = new AptosAccount(new Uint8Array(Buffer.from(key, "hex"))); const accountFrom = new AptosAccount(new Uint8Array(Buffer.from(key, "hex")));
let client: AptosClient; let client: AptosClient;
// if rpc arg is passed in, then override default rpc value for that network // if rpc arg is passed in, then override default rpc value for that network
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);
@ -190,12 +289,7 @@ export async function callEntryFunc(
]); ]);
const txPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction( const txPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
TxnBuilderTypes.EntryFunction.natural( TxnBuilderTypes.EntryFunction.natural(module, func, ty_args, args)
module,
func,
ty_args,
args
)
); );
const rawTxn = new TxnBuilderTypes.RawTransaction( const rawTxn = new TxnBuilderTypes.RawTransaction(
@ -205,7 +299,7 @@ export async function callEntryFunc(
BigInt(100000), //max gas to be used. TODO(csongor): we could compute this from the simulation below... BigInt(100000), //max gas to be used. TODO(csongor): we could compute this from the simulation below...
BigInt(100), //price per unit gas TODO(csongor): we should get this dynamically BigInt(100), //price per unit gas TODO(csongor): we should get this dynamically
BigInt(Math.floor(Date.now() / 1000) + 10), BigInt(Math.floor(Date.now() / 1000) + 10),
new TxnBuilderTypes.ChainId(chainId), new TxnBuilderTypes.ChainId(chainId)
); );
// simulate transaction before submitting // simulate transaction before submitting
@ -226,5 +320,8 @@ export async function callEntryFunc(
// strip the 0x prefix from a hex string // strip the 0x prefix from a hex string
function hex(x: string): Buffer { function hex(x: string): Buffer {
return Buffer.from(ethers.utils.hexlify(x, { allowMissingPrefix: true }).substring(2), "hex"); return Buffer.from(
ethers.utils.hexlify(x, { allowMissingPrefix: true }).substring(2),
"hex"
);
} }

View File

@ -3,11 +3,12 @@ import {
CHAIN_ID_APTOS, CHAIN_ID_APTOS,
coalesceChainId, coalesceChainId,
CONTRACTS, CONTRACTS,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } 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";
import sha3 from "js-sha3"; import sha3 from "js-sha3";
import { homedir } from "os";
import yargs from "yargs"; import yargs from "yargs";
import { import {
callEntryFunc, callEntryFunc,
@ -39,9 +40,9 @@ interface PackageBCS {
codeHash: Uint8Array; codeHash: Uint8Array;
} }
exports.command = "aptos"; export const command = "aptos";
exports.desc = "Aptos utilities"; export const desc = "Aptos utilities";
exports.builder = function (y: typeof yargs) { export const builder = function (y: typeof yargs) {
return ( return (
y y
// NOTE: there's no init-nft-bridge, because the native module initialiser // NOTE: there's no init-nft-bridge, because the native module initialiser
@ -452,9 +453,7 @@ exports.builder = function (y: typeof yargs) {
}, },
(argv) => { (argv) => {
checkBinary("aptos", README_URL); checkBinary("aptos", README_URL);
const os = require("os"); const cmd = `cd ${homedir()} && aptos node run-local-testnet --with-faucet --force-restart --assume-yes`;
const dir = os.homedir();
const cmd = `cd ${dir} && aptos node run-local-testnet --with-faucet --force-restart --assume-yes`;
runCommand(cmd, argv["validator-args"]); runCommand(cmd, argv["validator-args"]);
} }
) )
@ -524,3 +523,5 @@ function serializePackage(p: Package): PackageBCS {
codeHash, codeHash,
}; };
} }
export const handler = (argv) => {};

View File

@ -1,21 +1,21 @@
import yargs from "yargs";
import { import {
CHAINS, CHAINS,
assertChain, assertChain,
coalesceChainId, coalesceChainId,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import yargs from "yargs";
exports.command = "chain-id <chain>"; export const command = "chain-id <chain>";
exports.desc = export const desc =
"Print the wormhole chain ID integer associated with the specified chain name"; "Print the wormhole chain ID integer associated with the specified chain name";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y.positional("chain", { return y.positional("chain", {
describe: "Chain to query", describe: "Chain to query",
type: "string", type: "string",
choices: Object.keys(CHAINS), choices: Object.keys(CHAINS),
}); });
}; };
exports.handler = (argv) => { export const handler = (argv) => {
assertChain(argv["chain"]); assertChain(argv["chain"]);
console.log(coalesceChainId(argv["chain"])); console.log(coalesceChainId(argv["chain"]));
}; };

View File

@ -1,15 +1,15 @@
import yargs from "yargs";
import { import {
CHAINS, CHAINS,
assertChain, assertChain,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/cjs/utils/consts";
import { impossible } from "../vaa"; import yargs from "yargs";
import { CONTRACTS } from "../consts"; import { CONTRACTS } from "../consts";
import { getEmitterAddress } from "../emitter"; import { getEmitterAddress } from "../emitter";
import { impossible } from "../vaa";
exports.command = "contract <network> <chain> <module>"; export const command = "contract <network> <chain> <module>";
exports.desc = "Print contract address"; export const desc = "Print contract address";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y return y
.positional("network", { .positional("network", {
describe: "network", describe: "network",
@ -34,7 +34,7 @@ exports.builder = (y: typeof yargs) => {
required: false, required: false,
}); });
}; };
exports.handler = async (argv) => { export const handler = async (argv) => {
assertChain(argv["chain"]); assertChain(argv["chain"]);
const network = argv.network.toUpperCase(); const network = argv.network.toUpperCase();
if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") { if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") {

View File

@ -5,9 +5,9 @@ import {
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/cjs/utils/consts";
import { getEmitterAddress } from "../emitter"; import { getEmitterAddress } from "../emitter";
exports.command = "convert-to-emitter <chain> <address-to-convert>"; export const command = "convert-to-emitter <chain> <address-to-convert>";
exports.desc = "Print address in emitter address format"; export const desc = "Print address in emitter address format";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y return y
.positional("chain", { .positional("chain", {
describe: "Chain to query", describe: "Chain to query",
@ -19,7 +19,7 @@ exports.builder = (y: typeof yargs) => {
type: "string", type: "string",
}); });
}; };
exports.handler = async (argv) => { export const handler = async (argv) => {
assertChain(argv["chain"]); assertChain(argv["chain"]);
let chain = argv["chain"]; let chain = argv["chain"];
console.log(await getEmitterAddress(chain, argv["address-to-convert"])); console.log(await getEmitterAddress(chain, argv["address-to-convert"]));

View File

@ -16,18 +16,18 @@
// worm edit-vaa --vaa $VAA --gs $TESTNET_GUARDIAN_SECRET // worm edit-vaa --vaa $VAA --gs $TESTNET_GUARDIAN_SECRET
// //
import { Implementation__factory } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts"; import { Implementation__factory } from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import { Other } from "@certusone/wormhole-sdk/lib/cjs/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 { NETWORKS } from "../networks"; import { NETWORKS } from "../networks";
import { parse, Payload, serialiseVAA, sign, Signature, VAA } from "../vaa"; import { parse, Payload, serialiseVAA, sign, Signature, VAA } from "../vaa";
exports.command = "edit-vaa"; export const command = "edit-vaa";
exports.desc = "Edits or generates a VAA"; export const desc = "Edits or generates a VAA";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y return y
.option("vaa", { .option("vaa", {
alias: "v", alias: "v",
@ -103,7 +103,7 @@ exports.builder = (y: typeof yargs) => {
type: "string", type: "string",
}); });
}; };
exports.handler = async (argv) => { export const handler = async (argv) => {
let numSigs = 0; let numSigs = 0;
if (argv["signatures"]) { if (argv["signatures"]) {
numSigs += 1; numSigs += 1;

View File

@ -5,17 +5,23 @@ import {
CONTRACTS, CONTRACTS,
isEVMChain, isEVMChain,
toChainName, toChainName,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { homedir } from "os";
import yargs from "yargs"; import yargs from "yargs";
import {
getImplementation,
hijack_evm,
query_contract_evm,
setStorageAt,
} from "../evm";
import { NETWORKS } from "../networks"; import { NETWORKS } from "../networks";
import { runCommand, validator_args } from "../start-validator"; import { runCommand, validator_args } from "../start-validator";
import { evm_address } from "../utils"; import { evm_address } from "../utils";
exports.command = "evm"; export const command = "evm";
exports.desc = "EVM utilities"; export const desc = "EVM utilities";
exports.builder = function (y: typeof yargs) { export const builder = function (y: typeof yargs) {
const evm = require("../evm");
return y return y
.option("rpc", { .option("rpc", {
describe: "RPC endpoint", describe: "RPC endpoint",
@ -60,7 +66,7 @@ exports.builder = function (y: typeof yargs) {
}); });
}, },
async (argv) => { async (argv) => {
const result = await evm.setStorageAt( const result = await setStorageAt(
argv["rpc"], argv["rpc"],
evm_address(argv["contract-address"]), evm_address(argv["contract-address"]),
argv["storage-slot"], argv["storage-slot"],
@ -133,7 +139,7 @@ exports.builder = function (y: typeof yargs) {
let rpc = argv["rpc"] ?? NETWORKS[network][argv["chain"]].rpc; let rpc = argv["rpc"] ?? NETWORKS[network][argv["chain"]].rpc;
if (argv["implementation-only"]) { if (argv["implementation-only"]) {
console.log( console.log(
await evm.getImplementation( await getImplementation(
network, network,
argv["chain"], argv["chain"],
module, module,
@ -144,7 +150,7 @@ exports.builder = function (y: typeof yargs) {
} else { } else {
console.log( console.log(
JSON.stringify( JSON.stringify(
await evm.query_contract_evm( await query_contract_evm(
network, network,
argv["chain"], argv["chain"],
module, module,
@ -186,7 +192,7 @@ exports.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 evm.hijack_evm( await hijack_evm(
rpc, rpc,
argv["core-contract-address"], argv["core-contract-address"],
guardian_addresses, guardian_addresses,
@ -201,12 +207,12 @@ exports.builder = function (y: typeof yargs) {
return yargs.option("validator-args", validator_args); return yargs.option("validator-args", validator_args);
}, },
(argv) => { (argv) => {
const os = require("os"); const cmd = `cd ${homedir()} && npx ganache-cli -e 10000 --deterministic --time="1970-01-01T00:00:00+00:00"`;
const dir = os.homedir();
const cmd = `cd ${dir} && npx ganache-cli -e 10000 --deterministic --time="1970-01-01T00:00:00+00:00"`;
runCommand(cmd, argv["validator-args"]); runCommand(cmd, argv["validator-args"]);
} }
) )
.strict() .strict()
.demandCommand(); .demandCommand();
}; };
export const handler = (argv) => {};

View File

@ -1,3 +1,4 @@
import { tryNativeToHexString } from "@certusone/wormhole-sdk/lib/esm/utils/array";
import { import {
assertChain, assertChain,
ChainName, ChainName,
@ -5,7 +6,7 @@ import {
isCosmWasmChain, isCosmWasmChain,
isEVMChain, isEVMChain,
toChainId, toChainId,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } 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";
@ -46,9 +47,9 @@ function makeVAA(
return v; return v;
} }
exports.command = "generate"; export const command = "generate";
exports.desc = "generate VAAs (devnet and testnet only)"; export const desc = "generate VAAs (devnet and testnet only)";
exports.builder = function (y: typeof yargs) { export const builder = function (y: typeof yargs) {
return ( return (
y y
.option("guardian-secret", { .option("guardian-secret", {
@ -295,8 +296,7 @@ function parseAddress(chain: ChainName, address: string): string {
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 === "wormchain") { } else if (chain === "wormchain") {
const sdk = require("@certusone/wormhole-sdk/lib/cjs/utils/array"); return "0x" + tryNativeToHexString(address, chain);
return "0x" + sdk.tryNativeToHexString(address, chain);
} else if (chain === "btc") { } else if (chain === "btc") {
throw Error("btc is not supported yet"); throw Error("btc is not supported yet");
} else { } else {
@ -311,3 +311,5 @@ function parseCodeAddress(chain: ChainName, address: string): string {
return parseAddress(chain, address); return parseAddress(chain, address);
} }
} }
export const handler = (argv) => {};

View File

@ -1,12 +1,17 @@
import yargs from "yargs"; import yargs from "yargs";
import * as chainId from "./chainId";
import * as contractAddress from "./contractAddress";
import * as convertToEmitter from "./convert-to-emitter";
import * as rpc from "./rpc";
exports.command = "info"; export const command = "info";
exports.desc = "Contract, chain, rpc and address information utilities"; export const desc = "Contract, chain, rpc and address information utilities";
exports.builder = (y: typeof yargs) => {
// Imports modules logic from root commands, more info here -> https://github.com/yargs/yargs/blob/main/docs/advanced.md#providing-a-command-module // Imports modules logic from root commands, more info here -> https://github.com/yargs/yargs/blob/main/docs/advanced.md#providing-a-command-module
return y export const builder = (y: typeof yargs) =>
.command(require("./chainId")) y
.command(require("./rpc")) .command(chainId)
.command(require("./contractAddress")) .command(contractAddress)
.command(require("./convert-to-emitter")); .command(convertToEmitter)
}; .command(rpc);
export const handler = (argv) => {};

View File

@ -1,10 +1,10 @@
import yargs from "yargs"; import yargs from "yargs";
import { deploy_near, upgrade_near } from "../near";
// Near utilities // Near utilities
exports.command = "near"; export const command = "near";
exports.desc = "NEAR utilities"; export const desc = "NEAR utilities";
exports.builder = function (y: typeof yargs) { export const builder = function (y: typeof yargs) {
const near = require("../near");
return y return y
.option("module", { .option("module", {
alias: "m", alias: "m",
@ -55,7 +55,7 @@ exports.builder = function (y: typeof yargs) {
}); });
}, },
async (argv) => { async (argv) => {
await near.upgrade_near(argv); await upgrade_near(argv);
} }
) )
.command( .command(
@ -68,7 +68,9 @@ exports.builder = function (y: typeof yargs) {
}); });
}, },
async (argv) => { async (argv) => {
await near.deploy_near(argv); await deploy_near(argv);
} }
); );
}; };
export const handler = (argv) => {};

View File

@ -1,15 +1,15 @@
import yargs from "yargs"; import yargs from "yargs";
import { parse, vaaDigest } from "../vaa"; import { parse, vaaDigest } from "../vaa";
exports.command = "parse <vaa>"; export const command = "parse <vaa>";
exports.desc = "Parse a VAA (can be in either hex or base64 format)"; export const desc = "Parse a VAA (can be in either hex or base64 format)";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y.positional("vaa", { return y.positional("vaa", {
describe: "vaa", describe: "vaa",
type: "string", type: "string",
}); });
}; };
exports.handler = (argv) => { export const handler = (argv) => {
let buf: Buffer; let buf: Buffer;
try { try {
buf = Buffer.from(String(argv.vaa), "hex"); buf = Buffer.from(String(argv.vaa), "hex");

View File

@ -2,9 +2,9 @@ import { ethers } from "ethers";
import yargs from "yargs"; import yargs from "yargs";
import { hex } from "../utils"; import { hex } from "../utils";
exports.command = "recover <digest> <signature>"; export const command = "recover <digest> <signature>";
exports.desc = "Recover an address from a signature"; export const desc = "Recover an address from a signature";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y return y
.positional("digest", { .positional("digest", {
describe: "digest", describe: "digest",
@ -15,7 +15,7 @@ exports.builder = (y: typeof yargs) => {
type: "string", type: "string",
}); });
}; };
exports.handler = async (argv) => { export const handler = async (argv) => {
console.log( console.log(
ethers.utils.recoverAddress(hex(argv["digest"]), hex(argv["signature"])) ethers.utils.recoverAddress(hex(argv["digest"]), hex(argv["signature"]))
); );

View File

@ -1,13 +1,13 @@
import yargs from "yargs";
import { import {
CHAINS, CHAINS,
assertChain, assertChain,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import yargs from "yargs";
import { NETWORKS } from "../networks"; import { NETWORKS } from "../networks";
exports.command = "rpc <network> <chain>"; export const command = "rpc <network> <chain>";
exports.desc = "Print RPC address"; export const desc = "Print RPC address";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y return y
.positional("network", { .positional("network", {
describe: "network", describe: "network",
@ -20,7 +20,7 @@ exports.builder = (y: typeof yargs) => {
choices: Object.keys(CHAINS), choices: Object.keys(CHAINS),
}); });
}; };
exports.handler = async (argv) => { export const handler = async (argv) => {
assertChain(argv["chain"]); assertChain(argv["chain"]);
const network = argv.network.toUpperCase(); const network = argv.network.toUpperCase();
if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") { if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") {

View File

@ -6,13 +6,23 @@ import {
isEVMChain, isEVMChain,
isTerraChain, isTerraChain,
toChainName, toChainName,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import yargs from "yargs"; import yargs from "yargs";
import { execute_algorand } from "../algorand";
import { execute_evm } from "../evm";
import { execute_injective } from "../injective";
import { execute_near } from "../near";
import { execute_sei } from "../sei";
import { execute_solana } from "../solana";
import { submit as submitSui } from "../sui";
import { execute_terra } from "../terra";
import * as vaa from "../vaa"; import * as vaa from "../vaa";
import { execute_xpla } from "../xpla";
import { execute_aptos } from "../aptos";
exports.command = "submit <vaa>"; export const command = "submit <vaa>";
exports.desc = "Execute a VAA"; export const desc = "Execute a VAA";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y return y
.positional("vaa", { .positional("vaa", {
describe: "vaa", describe: "vaa",
@ -45,7 +55,7 @@ exports.builder = (y: typeof yargs) => {
required: false, required: false,
}); });
}; };
exports.handler = async (argv) => { export const handler = async (argv) => {
const vaa_hex = String(argv.vaa); const vaa_hex = String(argv.vaa);
const buf = Buffer.from(vaa_hex, "hex"); const buf = Buffer.from(vaa_hex, "hex");
const parsed_vaa = vaa.parse(buf); const parsed_vaa = vaa.parse(buf);
@ -99,8 +109,7 @@ exports.handler = async (argv) => {
"This VAA does not specify the target chain, please provide it by hand using the '--chain' flag." "This VAA does not specify the target chain, please provide it by hand using the '--chain' flag."
); );
} else if (isEVMChain(chain)) { } else if (isEVMChain(chain)) {
const evm = require("../evm"); await execute_evm(
await evm.execute_evm(
parsed_vaa.payload, parsed_vaa.payload,
buf, buf,
network, network,
@ -109,38 +118,29 @@ exports.handler = async (argv) => {
argv["rpc"] argv["rpc"]
); );
} else if (isTerraChain(chain)) { } else if (isTerraChain(chain)) {
const terra = require("../terra"); await execute_terra(parsed_vaa.payload, buf, network, chain);
await terra.execute_terra(parsed_vaa.payload, buf, network, chain);
} else if (chain === "solana" || chain === "pythnet") { } else if (chain === "solana" || chain === "pythnet") {
const solana = require("../solana"); await execute_solana(parsed_vaa, buf, network, chain);
await solana.execute_solana(parsed_vaa, buf, network, chain);
} else if (chain === "algorand") { } else if (chain === "algorand") {
const algorand = require("../algorand"); await execute_algorand(
await algorand.execute_algorand(
parsed_vaa.payload, parsed_vaa.payload,
new Uint8Array(Buffer.from(vaa_hex, "hex")), new Uint8Array(Buffer.from(vaa_hex, "hex")),
network network
); );
} else if (chain === "near") { } else if (chain === "near") {
const near = require("../near"); await execute_near(parsed_vaa.payload, vaa_hex, network);
await near.execute_near(parsed_vaa.payload, vaa_hex, network);
} else if (chain === "injective") { } else if (chain === "injective") {
const injective = require("../injective"); await execute_injective(parsed_vaa.payload, buf, network);
await injective.execute_injective(parsed_vaa.payload, buf, network);
} else if (chain === "xpla") { } else if (chain === "xpla") {
const xpla = require("../xpla"); await execute_xpla(parsed_vaa.payload, buf, network);
await xpla.execute_xpla(parsed_vaa.payload, buf, network);
} else if (chain === "sei") { } else if (chain === "sei") {
const sei = require("../sei"); await execute_sei(parsed_vaa.payload, buf, network);
await sei.execute_sei(parsed_vaa.payload, buf, network);
} 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") {
const sui = require("../sui"); await submitSui(parsed_vaa.payload, buf, network, argv["rpc"]);
await sui.submit(parsed_vaa.payload, buf, network, argv["rpc"]);
} else if (chain === "aptos") { } else if (chain === "aptos") {
const aptos = require("../aptos"); await execute_aptos(
await aptos.execute_aptos(
parsed_vaa.payload, parsed_vaa.payload,
buf, buf,
network, network,

View File

@ -7,9 +7,9 @@ import { addPublishMessageCommands } from "./publish_message";
import { addSetupCommands } from "./setup"; import { addSetupCommands } from "./setup";
import { addUtilsCommands } from "./utils"; import { addUtilsCommands } from "./utils";
exports.command = "sui"; export const command = "sui";
exports.desc = "Sui utilities"; export const desc = "Sui utilities";
exports.builder = function (y: typeof yargs) { export const builder = function (y: typeof yargs) {
return new Yargs(y) return new Yargs(y)
.addCommands(addBuildCommands) .addCommands(addBuildCommands)
.addCommands(addDeployCommands) .addCommands(addDeployCommands)
@ -21,3 +21,4 @@ exports.builder = function (y: typeof yargs) {
.strict() .strict()
.demandCommand(); .demandCommand();
}; };
export const handler = (argv) => {};

View File

@ -1,8 +1,8 @@
import { import {
ChainId, ChainId,
coalesceChainName, coalesceChainName,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import { parseTokenBridgeRegisterChainVaa } from "@certusone/wormhole-sdk/lib/cjs/vaa/tokenBridge"; import { parseTokenBridgeRegisterChainVaa } from "@certusone/wormhole-sdk/lib/esm/vaa/tokenBridge";
import { import {
JsonRpcProvider, JsonRpcProvider,
TransactionBlock, TransactionBlock,

View File

@ -1,14 +1,14 @@
// 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 yargs from "yargs"; 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 { CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import yargs from "yargs";
import { Implementation__factory } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts";
import { NETWORKS } from "../networks"; import { NETWORKS } from "../networks";
exports.command = "verify-vaa"; export const command = "verify-vaa";
exports.desc = "Verifies a VAA by querying the core contract on Ethereum"; export const desc = "Verifies a VAA by querying the core contract on Ethereum";
exports.builder = (y: typeof yargs) => { export const builder = (y: typeof yargs) => {
return y return y
.option("vaa", { .option("vaa", {
alias: "v", alias: "v",
@ -24,7 +24,7 @@ exports.builder = (y: typeof yargs) => {
required: true, required: true,
}); });
}; };
exports.handler = async (argv) => { export const handler = async (argv) => {
const network = argv.network.toUpperCase(); const network = argv.network.toUpperCase();
if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") { if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") {
throw Error(`Unknown network: ${network}`); throw Error(`Unknown network: ${network}`);

View File

@ -1,7 +1,7 @@
import { import {
CHAIN_ID_SOLANA, CHAIN_ID_SOLANA,
CONTRACTS as SDK_CONTRACTS, CONTRACTS as SDK_CONTRACTS,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
const OVERRIDES = { const OVERRIDES = {
MAINNET: { MAINNET: {

View File

@ -1,9 +1,9 @@
declare module 'elliptic' { declare module "elliptic" {
export interface BN { export interface BN {
length: number; length: number;
negative: number; negative: number;
words: Uint8Array; words: Uint8Array;
toString(format: string?): string; toString(format?: string): string;
} }
export interface Point { export interface Point {
@ -14,10 +14,13 @@ declare module 'elliptic' {
export interface KeyPair { export interface KeyPair {
getPrivate(): BN; getPrivate(): BN;
getPublic(): Point; getPublic(): Point;
sign(message: Buffer, options: any): { sign(
r: BN, message: Buffer,
s: BN, options: any
recoveryParam: number ): {
r: BN;
s: BN;
recoveryParam: number;
}; };
} }

View File

@ -1,13 +1,23 @@
import { ethers } from "ethers" import { ethers } from "ethers";
import { NETWORKS } from "./networks" import { NETWORKS } from "./networks";
import { encode, Encoding, impossible, Payload, typeWidth } from "./vaa" import { encode, Encoding, impossible, Payload, typeWidth } from "./vaa";
import axios from "axios"; import axios from "axios";
import * as celo from "@celo-tools/celo-ethers-wrapper"; import * as celo from "@celo-tools/celo-ethers-wrapper";
import { solidityKeccak256 } from "ethers/lib/utils" import { solidityKeccak256 } from "ethers/lib/utils";
import { CHAINS, CONTRACTS, Contracts, EVMChainName } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import {
import { BridgeImplementation__factory, Implementation__factory, NFTBridgeImplementation__factory } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts"; CHAINS,
CONTRACTS,
Contracts,
EVMChainName,
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import {
BridgeImplementation__factory,
Implementation__factory,
NFTBridgeImplementation__factory,
} from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
const _IMPLEMENTATION_SLOT = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc" const _IMPLEMENTATION_SLOT =
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
export async function query_contract_evm( export async function query_contract_evm(
network: "MAINNET" | "TESTNET" | "DEVNET", network: "MAINNET" | "TESTNET" | "DEVNET",
@ -16,28 +26,32 @@ export async function query_contract_evm(
contract_address: string | undefined, contract_address: string | undefined,
_rpc: string | undefined _rpc: string | undefined
): Promise<object> { ): Promise<object> {
let n = NETWORKS[network][chain] let n = NETWORKS[network][chain];
let rpc: string | undefined = _rpc ?? n.rpc; let rpc: string | undefined = _rpc ?? n.rpc;
if (rpc === undefined) { if (rpc === undefined) {
throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`) throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`);
} }
let contracts: Contracts = CONTRACTS[network][chain] let contracts: Contracts = CONTRACTS[network][chain];
const provider = new ethers.providers.JsonRpcProvider(rpc) const provider = new ethers.providers.JsonRpcProvider(rpc);
let result: any = {} let 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.core;
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}`);
} }
const core = Implementation__factory.connect(contract_address, provider) const core = Implementation__factory.connect(contract_address, provider);
result.address = contract_address result.address = contract_address;
result.currentGuardianSetIndex = await core.getCurrentGuardianSetIndex() result.currentGuardianSetIndex = await core.getCurrentGuardianSetIndex();
let guardianSetsPromise = Promise.all([...Array(result.currentGuardianSetIndex + 1).keys()].map((i) => core.getGuardianSet(i))) let guardianSetsPromise = Promise.all(
[...Array(result.currentGuardianSetIndex + 1).keys()].map((i) =>
core.getGuardianSet(i)
)
);
let [ let [
guardianSetExpiry, guardianSetExpiry,
chainId, chainId,
@ -47,7 +61,7 @@ export async function query_contract_evm(
governanceContract, governanceContract,
messageFee, messageFee,
implementationSlot, implementationSlot,
guardianSets guardianSets,
] = await Promise.all([ ] = await Promise.all([
core.getGuardianSetExpiry(), core.getGuardianSetExpiry(),
core.chainId(), core.chainId(),
@ -57,36 +71,47 @@ export async function query_contract_evm(
core.governanceContract(), core.governanceContract(),
core.messageFee(), core.messageFee(),
getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]), getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]),
guardianSetsPromise guardianSetsPromise,
]) ]);
result.guardianSetExpiry = guardianSetExpiry result.guardianSetExpiry = guardianSetExpiry;
result.chainId = chainId result.chainId = chainId;
result.evmChainId = evmChainId.toString() result.evmChainId = evmChainId.toString();
result.isFork = isFork result.isFork = isFork;
result.governanceChainId = governanceChainId result.governanceChainId = governanceChainId;
result.governanceContract = governanceContract result.governanceContract = governanceContract;
result.messageFee = messageFee result.messageFee = messageFee;
result.implementation = implementationSlot[0] result.implementation = implementationSlot[0];
result.isInitialized = await core.isInitialized(result.implementation) result.isInitialized = await core.isInitialized(result.implementation);
result.guardianSet = {} result.guardianSet = {};
for (let [i, guardianSet] of guardianSets.entries()) { for (let [i, guardianSet] of guardianSets.entries()) {
result.guardianSet[i] = { keys: guardianSet[0], expiry: guardianSet[1] } result.guardianSet[i] = {
keys: guardianSet[0],
expiry: guardianSet[1],
};
} }
break break;
case "TokenBridge": case "TokenBridge":
contract_address = contract_address ? contract_address : contracts.token_bridge; contract_address = contract_address
? contract_address
: contracts.token_bridge;
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}`);
} }
const tb = BridgeImplementation__factory.connect(contract_address, provider) const tb = BridgeImplementation__factory.connect(
result.address = contract_address contract_address,
provider
);
result.address = contract_address;
const registrationsPromise = Promise.all( const registrationsPromise = Promise.all(
Object.entries(CHAINS) Object.entries(CHAINS)
.filter(([c_name, _]) => c_name !== chain && c_name !== "unset") .filter(([c_name, _]) => c_name !== chain && c_name !== "unset")
.map(async ([c_name, c_id]) => [c_name, await tb.bridgeContracts(c_id)]) .map(async ([c_name, c_id]) => [
) c_name,
await tb.bridgeContracts(c_id),
])
);
let [ let [
wormhole, wormhole,
implementationSlotTb, implementationSlotTb,
@ -98,7 +123,7 @@ export async function query_contract_evm(
governanceChainIdTb, governanceChainIdTb,
governanceContractTb, governanceContractTb,
WETH, WETH,
registrations registrations,
] = await Promise.all([ ] = await Promise.all([
tb.wormhole(), tb.wormhole(),
getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]), getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]),
@ -110,37 +135,45 @@ export async function query_contract_evm(
tb.governanceChainId(), tb.governanceChainId(),
tb.governanceContract(), tb.governanceContract(),
tb.WETH(), tb.WETH(),
registrationsPromise registrationsPromise,
]) ]);
result.wormhole = wormhole result.wormhole = wormhole;
result.implementation = implementationSlotTb[0] result.implementation = implementationSlotTb[0];
result.isInitialized = await tb.isInitialized(result.implementation) result.isInitialized = await tb.isInitialized(result.implementation);
result.tokenImplementation = tokenImplementation result.tokenImplementation = tokenImplementation;
result.chainId = chainIdTb result.chainId = chainIdTb;
result.finality = finality result.finality = finality;
result.evmChainId = evmChainIdTb.toString() result.evmChainId = evmChainIdTb.toString();
result.isFork = isForkTb result.isFork = isForkTb;
result.governanceChainId = governanceChainIdTb result.governanceChainId = governanceChainIdTb;
result.governanceContract = governanceContractTb result.governanceContract = governanceContractTb;
result.WETH = WETH result.WETH = WETH;
result.registrations = {} result.registrations = {};
for (let [c_name, c] of registrations) { for (let [c_name, c] of registrations) {
result.registrations[c_name] = c result.registrations[c_name] = c;
} }
break break;
case "NFTBridge": case "NFTBridge":
contract_address = contract_address ? contract_address : contracts.nft_bridge; contract_address = contract_address
? contract_address
: contracts.nft_bridge;
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}`);
} }
const nb = NFTBridgeImplementation__factory.connect(contract_address, provider) const nb = NFTBridgeImplementation__factory.connect(
result.address = contract_address contract_address,
provider
);
result.address = contract_address;
const registrationsPromiseNb = Promise.all( const registrationsPromiseNb = Promise.all(
Object.entries(CHAINS) Object.entries(CHAINS)
.filter(([c_name, _]) => c_name !== chain && c_name !== "unset") .filter(([c_name, _]) => c_name !== chain && c_name !== "unset")
.map(async ([c_name, c_id]) => [c_name, await nb.bridgeContracts(c_id)]) .map(async ([c_name, c_id]) => [
) c_name,
await nb.bridgeContracts(c_id),
])
);
let [ let [
wormholeNb, wormholeNb,
implementationSlotNb, implementationSlotNb,
@ -151,7 +184,7 @@ export async function query_contract_evm(
isForkNb, isForkNb,
governanceChainIdNb, governanceChainIdNb,
governanceContractNb, governanceContractNb,
registrationsNb registrationsNb,
] = await Promise.all([ ] = await Promise.all([
nb.wormhole(), nb.wormhole(),
getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]), getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]),
@ -162,29 +195,29 @@ export async function query_contract_evm(
maybeUnsupported(nb.isFork()), maybeUnsupported(nb.isFork()),
nb.governanceChainId(), nb.governanceChainId(),
nb.governanceContract(), nb.governanceContract(),
registrationsPromiseNb registrationsPromiseNb,
]) ]);
result.wormhole = wormholeNb result.wormhole = wormholeNb;
result.implementation = implementationSlotNb[0] result.implementation = implementationSlotNb[0];
result.isInitialized = await nb.isInitialized(result.implementation) result.isInitialized = await nb.isInitialized(result.implementation);
result.tokenImplementation = tokenImplementationNb result.tokenImplementation = tokenImplementationNb;
result.chainId = chainIdNb result.chainId = chainIdNb;
result.finality = finalityNb result.finality = finalityNb;
result.evmChainId = evmChainIdNb.toString() result.evmChainId = evmChainIdNb.toString();
result.isFork = isForkNb result.isFork = isForkNb;
result.governanceChainId = governanceChainIdNb result.governanceChainId = governanceChainIdNb;
result.governanceContract = governanceContractNb result.governanceContract = governanceContractNb;
result.registrations = {} result.registrations = {};
for (let [c_name, c] of registrationsNb) { for (let [c_name, c] of registrationsNb) {
result.registrations[c_name] = c result.registrations[c_name] = c;
} }
break break;
default: default:
impossible(module) impossible(module);
} }
return result return result;
} }
export async function getImplementation( export async function getImplementation(
@ -194,29 +227,35 @@ export async function getImplementation(
contract_address: string | undefined, contract_address: string | undefined,
_rpc: string | undefined _rpc: string | undefined
): Promise<ethers.BigNumber> { ): Promise<ethers.BigNumber> {
let n = NETWORKS[network][chain] let n = NETWORKS[network][chain];
let rpc: string | undefined = _rpc ?? n.rpc; let rpc: string | undefined = _rpc ?? n.rpc;
if (rpc === undefined) { if (rpc === undefined) {
throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`) throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`);
} }
let contracts: Contracts = CONTRACTS[network][chain] let 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.core;
break break;
case "TokenBridge": case "TokenBridge":
contract_address = contract_address ? contract_address : contracts.token_bridge; contract_address = contract_address
break ? contract_address
: contracts.token_bridge;
break;
case "NFTBridge": case "NFTBridge":
contract_address = contract_address ? contract_address : contracts.nft_bridge; contract_address = contract_address
break ? contract_address
: contracts.nft_bridge;
break;
default: default:
impossible(module) impossible(module);
} }
return (await getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]))[0] return (
await getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"])
)[0];
} }
export async function execute_evm( export async function execute_evm(
@ -227,35 +266,35 @@ export async function execute_evm(
contract_address: string | undefined, contract_address: string | undefined,
_rpc: string | undefined _rpc: string | undefined
) { ) {
let n = NETWORKS[network][chain] let n = NETWORKS[network][chain];
let rpc: string | undefined = _rpc ?? n.rpc; let rpc: string | undefined = _rpc ?? n.rpc;
if (rpc === undefined) { if (rpc === undefined) {
throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`) throw Error(`No ${network} rpc defined for ${chain} (see networks.ts)`);
} }
if (!n.key) { if (!n.key) {
throw Error(`No ${network} key defined for ${chain} (see networks.ts)`) throw Error(`No ${network} key defined for ${chain} (see networks.ts)`);
} }
let key: string = n.key let key: string = n.key;
let contracts: Contracts = CONTRACTS[network][chain] let contracts: Contracts = CONTRACTS[network][chain];
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);
} else { } else {
provider = new ethers.providers.JsonRpcProvider(rpc) provider = new ethers.providers.JsonRpcProvider(rpc);
signer = new ethers.Wallet(key, provider) signer = new ethers.Wallet(key, provider);
} }
// Here we apply a set of chain-specific overrides. // Here we apply a set of chain-specific overrides.
// 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(n.rpc) overrides = await getKaruraGasParams(n.rpc);
} else if (chain === "polygon") { } else if (chain === "polygon") {
let feeData = await provider.getFeeData(); let feeData = await provider.getFeeData();
overrides = { overrides = {
@ -263,105 +302,128 @@ export async function execute_evm(
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() };
} }
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.core;
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}`);
} }
let c = new Implementation__factory(signer) let c = new Implementation__factory(signer);
let cb = c.attach(contract_address) let cb = c.attach(contract_address);
switch (payload.type) { switch (payload.type) {
case "GuardianSetUpgrade": case "GuardianSetUpgrade":
console.log("Submitting new guardian set") console.log("Submitting new guardian set");
console.log("Hash: " + (await cb.submitNewGuardianSet(vaa, overrides)).hash) console.log(
break "Hash: " + (await cb.submitNewGuardianSet(vaa, overrides)).hash
);
break;
case "ContractUpgrade": case "ContractUpgrade":
console.log("Upgrading core contract") console.log("Upgrading core contract");
console.log("Hash: " + (await cb.submitContractUpgrade(vaa, overrides)).hash) console.log(
break "Hash: " + (await cb.submitContractUpgrade(vaa, overrides)).hash
);
break;
case "RecoverChainId": case "RecoverChainId":
console.log("Recovering chain ID") console.log("Recovering chain ID");
console.log("Hash: " + (await cb.submitRecoverChainId(vaa, overrides)).hash) console.log(
break "Hash: " + (await cb.submitRecoverChainId(vaa, overrides)).hash
);
break;
default: default:
impossible(payload) impossible(payload);
} }
break break;
case "NFTBridge": case "NFTBridge":
contract_address = contract_address ? contract_address : contracts.nft_bridge; contract_address = contract_address
? contract_address
: contracts.nft_bridge;
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}`);
} }
let n = new NFTBridgeImplementation__factory(signer) let n = new NFTBridgeImplementation__factory(signer);
let nb = n.attach(contract_address) let nb = n.attach(contract_address);
switch (payload.type) { switch (payload.type) {
case "ContractUpgrade": case "ContractUpgrade":
console.log("Upgrading contract") console.log("Upgrading contract");
console.log("Hash: " + (await nb.upgrade(vaa, overrides)).hash) console.log("Hash: " + (await nb.upgrade(vaa, overrides)).hash);
console.log("Don't forget to verify the new implementation! See ethereum/VERIFY.md for instructions") console.log(
break "Don't forget to verify the new implementation! See ethereum/VERIFY.md for instructions"
);
break;
case "RecoverChainId": case "RecoverChainId":
console.log("Recovering chain ID") console.log("Recovering chain ID");
console.log("Hash: " + (await nb.submitRecoverChainId(vaa, overrides)).hash) console.log(
break "Hash: " + (await nb.submitRecoverChainId(vaa, overrides)).hash
);
break;
case "RegisterChain": case "RegisterChain":
console.log("Registering chain") console.log("Registering chain");
console.log("Hash: " + (await nb.registerChain(vaa, overrides)).hash) console.log("Hash: " + (await nb.registerChain(vaa, overrides)).hash);
break break;
case "Transfer": case "Transfer":
console.log("Completing transfer") console.log("Completing transfer");
console.log("Hash: " + (await nb.completeTransfer(vaa, overrides)).hash) console.log(
break "Hash: " + (await nb.completeTransfer(vaa, overrides)).hash
);
break;
default: default:
impossible(payload) impossible(payload);
} }
break break;
case "TokenBridge": case "TokenBridge":
contract_address = contract_address ? contract_address : contracts.token_bridge; contract_address = contract_address
? contract_address
: contracts.token_bridge;
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}`);
} }
let t = new BridgeImplementation__factory(signer) let t = new BridgeImplementation__factory(signer);
let tb = t.attach(contract_address) let tb = t.attach(contract_address);
switch (payload.type) { switch (payload.type) {
case "ContractUpgrade": case "ContractUpgrade":
console.log("Upgrading contract") console.log("Upgrading contract");
console.log("Hash: " + (await tb.upgrade(vaa, overrides)).hash) console.log("Hash: " + (await tb.upgrade(vaa, overrides)).hash);
console.log("Don't forget to verify the new implementation! See ethereum/VERIFY.md for instructions") console.log(
break "Don't forget to verify the new implementation! See ethereum/VERIFY.md for instructions"
);
break;
case "RecoverChainId": case "RecoverChainId":
console.log("Recovering chain ID") console.log("Recovering chain ID");
console.log("Hash: " + (await tb.submitRecoverChainId(vaa, overrides)).hash) console.log(
break "Hash: " + (await tb.submitRecoverChainId(vaa, overrides)).hash
);
break;
case "RegisterChain": case "RegisterChain":
console.log("Registering chain") console.log("Registering chain");
console.log("Hash: " + (await tb.registerChain(vaa, overrides)).hash) console.log("Hash: " + (await tb.registerChain(vaa, overrides)).hash);
break break;
case "Transfer": case "Transfer":
console.log("Completing transfer") console.log("Completing transfer");
console.log("Hash: " + (await tb.completeTransfer(vaa, overrides)).hash) console.log(
break "Hash: " + (await tb.completeTransfer(vaa, overrides)).hash
);
break;
case "AttestMeta": case "AttestMeta":
console.log("Creating wrapped token") console.log("Creating wrapped token");
console.log("Hash: " + (await tb.createWrapped(vaa, overrides)).hash) console.log("Hash: " + (await tb.createWrapped(vaa, overrides)).hash);
break break;
case "TransferWithPayload": case "TransferWithPayload":
console.log("Completing transfer with payload") console.log("Completing transfer with payload");
console.log("Hash: " + (await tb.completeTransferWithPayload(vaa, overrides)).hash) console.log(
break "Hash: " +
(await tb.completeTransferWithPayload(vaa, overrides)).hash
);
break;
default: default:
impossible(payload) impossible(payload);
break break;
} }
break break;
default: default:
impossible(payload) impossible(payload);
} }
} }
@ -392,39 +454,65 @@ export async function hijack_evm(
guardian_addresses: string[], guardian_addresses: string[],
new_guardian_set_index: number | undefined new_guardian_set_index: number | undefined
): Promise<void> { ): Promise<void> {
const GUARDIAN_SETS_SLOT = 0x02 const GUARDIAN_SETS_SLOT = 0x02;
const GUARDIAN_SET_INDEX_SLOT = 0x3 const GUARDIAN_SET_INDEX_SLOT = 0x3;
const provider = new ethers.providers.JsonRpcProvider(rpc) const provider = new ethers.providers.JsonRpcProvider(rpc);
const core = Implementation__factory.connect(contract_address, provider) const core = Implementation__factory.connect(contract_address, provider);
let guardianSetIndex: number let guardianSetIndex: number;
let guardianSetExpiry: number let guardianSetExpiry: number;
[guardianSetIndex, guardianSetExpiry] = await getStorageAt(rpc, contract_address, GUARDIAN_SET_INDEX_SLOT, ["uint32", "uint32"]) [guardianSetIndex, guardianSetExpiry] = await getStorageAt(
console.log("Attempting to hijack core bridge guardian set.") rpc,
const current_set = await core.getGuardianSet(guardianSetIndex) contract_address,
console.log(`Current guardian set (index ${guardianSetIndex}):`) GUARDIAN_SET_INDEX_SLOT,
console.log(current_set[0]) ["uint32", "uint32"]
);
console.log("Attempting to hijack core bridge guardian set.");
const current_set = await core.getGuardianSet(guardianSetIndex);
console.log(`Current guardian set (index ${guardianSetIndex}):`);
console.log(current_set[0]);
if (new_guardian_set_index !== undefined) { if (new_guardian_set_index !== undefined) {
await setStorageAt(rpc, contract_address, GUARDIAN_SET_INDEX_SLOT, ["uint32", "uint32"], [new_guardian_set_index, guardianSetExpiry]) await setStorageAt(
guardianSetIndex = await core.getCurrentGuardianSetIndex() rpc,
contract_address,
GUARDIAN_SET_INDEX_SLOT,
["uint32", "uint32"],
[new_guardian_set_index, guardianSetExpiry]
);
guardianSetIndex = await core.getCurrentGuardianSetIndex();
if (new_guardian_set_index !== guardianSetIndex) { if (new_guardian_set_index !== guardianSetIndex) {
throw Error("Failed to update guardian set index.") throw Error("Failed to update guardian set index.");
} else { } else {
console.log(`Guardian set index updated to ${new_guardian_set_index}`) console.log(`Guardian set index updated to ${new_guardian_set_index}`);
} }
} }
const addresses_slot = computeMappingElemSlot(GUARDIAN_SETS_SLOT, guardianSetIndex) const addresses_slot = computeMappingElemSlot(
console.log(`Writing new set of guardians into set ${guardianSetIndex}...`) GUARDIAN_SETS_SLOT,
guardianSetIndex
);
console.log(`Writing new set of guardians into set ${guardianSetIndex}...`);
guardian_addresses.forEach(async (address, i) => { guardian_addresses.forEach(async (address, i) => {
await setStorageAt(rpc, contract_address, computeArrayElemSlot(addresses_slot, i), ["address"], [address]) await setStorageAt(
}) rpc,
await setStorageAt(rpc, contract_address, addresses_slot, ["uint256"], [guardian_addresses.length]) contract_address,
const after_guardian_set_index = await core.getCurrentGuardianSetIndex() computeArrayElemSlot(addresses_slot, i),
const new_set = await core.getGuardianSet(after_guardian_set_index) ["address"],
console.log(`Current guardian set (index ${after_guardian_set_index}):`) [address]
console.log(new_set[0]) );
console.log("Success.") });
await setStorageAt(
rpc,
contract_address,
addresses_slot,
["uint256"],
[guardian_addresses.length]
);
const after_guardian_set_index = await core.getCurrentGuardianSetIndex();
const new_set = await core.getGuardianSet(after_guardian_set_index);
console.log(`Current guardian set (index ${after_guardian_set_index}):`);
console.log(new_set[0]);
console.log("Success.");
} }
async function getKaruraGasParams(rpc: string): Promise<{ async function getKaruraGasParams(rpc: string): Promise<{
@ -461,9 +549,9 @@ async function getKaruraGasParams(rpc: string): Promise<{
// //
// [1]: https://docs.soliditylang.org/en/v0.8.14/internals/layout_in_storage.html // [1]: https://docs.soliditylang.org/en/v0.8.14/internals/layout_in_storage.html
export type StorageSlot = ethers.BigNumber export type StorageSlot = ethers.BigNumber;
// we're a little more permissive in contravariant positions... // we're a little more permissive in contravariant positions...
export type StorageSlotish = ethers.BigNumberish export type StorageSlotish = ethers.BigNumberish;
/** /**
* *
@ -472,8 +560,13 @@ export type StorageSlotish = ethers.BigNumberish
* @param array_slot the storage slot of the array variable * @param array_slot the storage slot of the array variable
* @param offset the index of the element to compute the storage slot for * @param offset the index of the element to compute the storage slot for
*/ */
export function computeArrayElemSlot(array_slot: StorageSlotish, offset: number): StorageSlot { export function computeArrayElemSlot(
return ethers.BigNumber.from(solidityKeccak256(["bytes"], [array_slot])).add(offset) array_slot: StorageSlotish,
offset: number
): StorageSlot {
return ethers.BigNumber.from(solidityKeccak256(["bytes"], [array_slot])).add(
offset
);
} }
/** /**
@ -483,9 +576,15 @@ export function computeArrayElemSlot(array_slot: StorageSlotish, offset: number)
* @param map_slot the storage slot of the mapping variable * @param map_slot the storage slot of the mapping variable
* @param key the key to compute the storage slot for * @param key the key to compute the storage slot for
*/ */
export function computeMappingElemSlot(map_slot: StorageSlotish, key: any): StorageSlot { export function computeMappingElemSlot(
const slot_preimage = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [key, map_slot]) map_slot: StorageSlotish,
return ethers.BigNumber.from(solidityKeccak256(["bytes"], [slot_preimage])) key: any
): StorageSlot {
const slot_preimage = ethers.utils.defaultAbiCoder.encode(
["uint256", "uint256"],
[key, map_slot]
);
return ethers.BigNumber.from(solidityKeccak256(["bytes"], [slot_preimage]));
} }
/** /**
@ -505,23 +604,31 @@ export function computeMappingElemSlot(map_slot: StorageSlotish, key: any): Stor
* *
* @returns _values the values to write into the slot (packed) * @returns _values the values to write into the slot (packed)
*/ */
async function getStorageAt(rpc: string, contract_address: string, storage_slot: StorageSlotish, types: Encoding[]): Promise<any[]> { async function getStorageAt(
const total = types.map((typ) => typeWidth(typ)).reduce((x, y) => (x + y)) rpc: string,
contract_address: string,
storage_slot: StorageSlotish,
types: Encoding[]
): Promise<any[]> {
const total = types.map((typ) => typeWidth(typ)).reduce((x, y) => x + y);
if (total > 32) { if (total > 32) {
throw new Error(`Storage slots can contain a maximum of 32 bytes. Total size of ${types} is ${total} bytes.`) throw new Error(
`Storage slots can contain a maximum of 32 bytes. Total size of ${types} is ${total} bytes.`
);
} }
const string_val: string = const string_val: string = await new ethers.providers.JsonRpcProvider(
await (new ethers.providers.JsonRpcProvider(rpc).getStorageAt(contract_address, storage_slot)) rpc
let val = ethers.BigNumber.from(string_val) ).getStorageAt(contract_address, storage_slot);
let ret: any[] = [] let val = ethers.BigNumber.from(string_val);
let ret: any[] = [];
// we decode the elements one by one, by shifting down the stuff we've parsed already // we decode the elements one by one, by shifting down the stuff we've parsed already
types.forEach((typ) => { types.forEach((typ) => {
const padded = ethers.utils.defaultAbiCoder.encode(["uint256"], [val]) const padded = ethers.utils.defaultAbiCoder.encode(["uint256"], [val]);
ret.push(ethers.utils.defaultAbiCoder.decode([typ], padded)[0]) ret.push(ethers.utils.defaultAbiCoder.decode([typ], padded)[0]);
val = val.shr(typeWidth(typ) * 8) val = val.shr(typeWidth(typ) * 8);
}) });
return ret return ret;
} }
/** /**
@ -542,7 +649,13 @@ async function getStorageAt(rpc: string, contract_address: string, storage_slot:
* *
* @returns the `data` property of the JSON response * @returns the `data` property of the JSON response
*/ */
export async function setStorageAt(rpc: string, contract_address: string, storage_slot: StorageSlotish, types: Encoding[], values: any[]): Promise<any> { export async function setStorageAt(
rpc: string,
contract_address: string,
storage_slot: StorageSlotish,
types: Encoding[],
values: any[]
): Promise<any> {
// we need to reverse the values and types arrays, because the first element // we need to reverse the values and types arrays, because the first element
// is stored at the rightmost bytes. // is stored at the rightmost bytes.
// //
@ -550,42 +663,51 @@ export async function setStorageAt(rpc: string, contract_address: string, storag
// uint32 a // uint32 a
// uint32 b // uint32 b
// will be stored as 0x...b...a // will be stored as 0x...b...a
const _values = values.reverse() const _values = values.reverse();
const _types = types.reverse() const _types = types.reverse();
const total = _types.map((typ) => typeWidth(typ)).reduce((x, y) => (x + y)) const total = _types.map((typ) => typeWidth(typ)).reduce((x, y) => x + y);
// ensure that the types fit into a slot // ensure that the types fit into a slot
if (total > 32) { if (total > 32) {
throw new Error(`Storage slots can contain a maximum of 32 bytes. Total size of ${_types} is ${total} bytes.`) throw new Error(
`Storage slots can contain a maximum of 32 bytes. Total size of ${_types} is ${total} bytes.`
);
} }
if (_types.length !== _values.length) { if (_types.length !== _values.length) {
throw new Error(`Expected ${_types.length} value(s), but got ${_values.length}.`) throw new Error(
`Expected ${_types.length} value(s), but got ${_values.length}.`
);
} }
// as far as I could tell, `ethers` doesn't provide a way to pack multiple // as far as I could tell, `ethers` doesn't provide a way to pack multiple
// values into a single slot (the abi coder pads everything to 32 bytes), so we do it ourselves // values into a single slot (the abi coder pads everything to 32 bytes), so we do it ourselves
const val = "0x" + _types.map((typ, i) => encode(typ, _values[i])).reduce((x, y) => x + y).padStart(64, "0") const val =
"0x" +
_types
.map((typ, i) => encode(typ, _values[i]))
.reduce((x, y) => x + y)
.padStart(64, "0");
// format the storage slot // format the storage slot
const slot = ethers.utils.defaultAbiCoder.encode(["uint256"], [storage_slot]) const slot = ethers.utils.defaultAbiCoder.encode(["uint256"], [storage_slot]);
console.log(`slot ${slot} := ${val}`) console.log(`slot ${slot} := ${val}`);
return (await axios.post(rpc, { return (
await axios.post(rpc, {
id: 0, id: 0,
jsonrpc: "2.0", jsonrpc: "2.0",
method: "hardhat_setStorageAt", method: "hardhat_setStorageAt",
params: [ params: [contract_address, slot, val],
contract_address, })
slot, ).data;
val,
],
})).data
} }
async function maybeUnsupported<T>(query: Promise<T>): Promise<T | "unsupported"> { async function maybeUnsupported<T>(
query: Promise<T>
): Promise<T | "unsupported"> {
try { try {
return await query return await query;
} catch (e) { } catch (e) {
if (e.reason === "unsupported") { if (e.reason === "unsupported") {
return e.reason return e.reason;
} }
throw e throw e;
} }
} }

View File

@ -1,4 +1,4 @@
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import { getNetworkInfo, Network } from "@injectivelabs/networks"; import { getNetworkInfo, Network } from "@injectivelabs/networks";
import { import {
ChainRestAuthApi, ChainRestAuthApi,

View File

@ -10,17 +10,47 @@
// for lack of a better way to stop this, we patch the console.info function to // for lack of a better way to stop this, we patch the console.info function to
// drop that particular message... // drop that particular message...
// </sigh> // </sigh>
const info = console.info; const infoTemp = console.info;
console.info = function (x: string) { console.info = function (x: string) {
if (x != "secp256k1 unavailable, reverting to browser version") { if (x != "secp256k1 unavailable, reverting to browser version") {
info(x); infoTemp(x);
} }
}; };
import yargs from "yargs"; import yargs from "yargs";
import { hideBin } from "yargs/helpers"; import { hideBin } from "yargs/helpers";
// https://github.com/yargs/yargs/blob/main/docs/advanced.md#example-command-hierarchy-using-indexmjs
import * as aptos from "./cmds/aptos";
import * as chainId from "./cmds/chainId";
import * as contractAddress from "./cmds/contractAddress";
import * as editVaa from "./cmds/edit-vaa";
import * as evm from "./cmds/evm";
import * as generate from "./cmds/generate";
import * as info from "./cmds/info";
import * as near from "./cmds/near";
import * as parse from "./cmds/parse";
import * as recover from "./cmds/recover";
import * as rpc from "./cmds/rpc";
import * as submit from "./cmds/submit";
import * as sui from "./cmds/sui";
import * as verifyVaa from "./cmds/verify-vaa";
yargs(hideBin(process.argv)) yargs(hideBin(process.argv))
.commandDir("cmds", { recurse: true }) // https://github.com/yargs/yargs/blob/main/docs/advanced.md#commanddirdirectory-opts
// can't use `.commandDir` because bundling + tree-shaking
.command(aptos)
.command(chainId)
.command(contractAddress)
.command(editVaa)
.command(evm)
.command(generate)
.command(info)
.command(near)
.command(parse)
.command(recover)
.command(rpc)
.command(submit)
.command(sui)
.command(verifyVaa)
.strict() .strict()
.demandCommand().argv; .demandCommand().argv;

View File

@ -1,11 +1,11 @@
import { impossible, Payload } from "./vaa"; import { impossible, Payload } from "./vaa";
import { NETWORKS } from "./networks"; import { NETWORKS } from "./networks";
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
const { parseSeedPhrase, generateSeedPhrase } = require("near-seed-phrase"); import { parseSeedPhrase, generateSeedPhrase } from "near-seed-phrase";
const fs = require("fs"); import BN from "bn.js";
import { readFileSync } from "fs";
const BN = require("bn.js"); import { Account, connect, KeyPair } from "near-api-js";
const nearAPI = require("near-api-js"); import { InMemoryKeyStore } from "near-api-js/lib/key_stores";
function default_near_args(argv) { function default_near_args(argv) {
let network = argv["n"].toUpperCase(); let network = argv["n"].toUpperCase();
@ -44,21 +44,22 @@ function default_near_args(argv) {
export async function deploy_near(argv) { export async function deploy_near(argv) {
default_near_args(argv); default_near_args(argv);
let masterKey = nearAPI.utils.KeyPair.fromString(argv["key"]); let masterKey = KeyPair.fromString(argv["key"]);
let keyStore = new nearAPI.keyStores.InMemoryKeyStore(); let keyStore = new InMemoryKeyStore();
keyStore.setKey(argv["networkId"], argv["account"], masterKey); keyStore.setKey(argv["networkId"], argv["account"], masterKey);
keyStore.setKey(argv["networkId"], argv["target"], masterKey); keyStore.setKey(argv["networkId"], argv["target"], masterKey);
let near = await nearAPI.connect({ let near = await connect({
deps: { deps: {
keyStore, keyStore,
}, },
networkId: argv["networkId"], networkId: argv["networkId"],
nodeUrl: argv["rpc"], nodeUrl: argv["rpc"],
headers: {},
}); });
let masterAccount = new nearAPI.Account(near.connection, argv["account"]); let masterAccount = new Account(near.connection, argv["account"]);
let targetAccount = new nearAPI.Account(near.connection, argv["target"]); let targetAccount = new Account(near.connection, argv["target"]);
console.log(argv); console.log(argv);
@ -75,34 +76,33 @@ export async function deploy_near(argv) {
} }
console.log("deploying contract"); console.log("deploying contract");
console.log( console.log(await targetAccount.deployContract(readFileSync(argv["file"])));
await targetAccount.deployContract(await fs.readFileSync(argv["file"]))
);
} }
export async function upgrade_near(argv) { export async function upgrade_near(argv) {
default_near_args(argv); default_near_args(argv);
let masterKey = nearAPI.utils.KeyPair.fromString(argv["key"]); let masterKey = KeyPair.fromString(argv["key"]);
let keyStore = new nearAPI.keyStores.InMemoryKeyStore(); let keyStore = new InMemoryKeyStore();
keyStore.setKey(argv["networkId"], argv["account"], masterKey); keyStore.setKey(argv["networkId"], argv["account"], masterKey);
let near = await nearAPI.connect({ let near = await connect({
deps: { deps: {
keyStore, keyStore,
}, },
networkId: argv["networkId"], networkId: argv["networkId"],
nodeUrl: argv["rpc"], nodeUrl: argv["rpc"],
headers: {},
}); });
let masterAccount = new nearAPI.Account(near.connection, argv["account"]); let masterAccount = new Account(near.connection, argv["account"]);
let result = await masterAccount.functionCall({ let result = await masterAccount.functionCall({
contractId: argv["target"], contractId: argv["target"],
methodName: "update_contract", methodName: "update_contract",
args: await fs.readFileSync(argv["file"]), args: readFileSync(argv["file"]),
attachedDeposit: "22797900000000000000000000", attachedDeposit: new BN("22797900000000000000000000"),
gas: 300000000000000, gas: new BN("300000000000000"),
}); });
console.log(result); console.log(result);
} }
@ -132,7 +132,7 @@ export async function execute_near(
console.log("Upgrading core contract"); console.log("Upgrading core contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on near") throw new Error("RecoverChainId not supported on near");
default: default:
impossible(payload); impossible(payload);
} }
@ -148,7 +148,7 @@ export async function execute_near(
console.log("Upgrading contract"); console.log("Upgrading contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on near") throw new Error("RecoverChainId not supported on near");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
break; break;
@ -170,7 +170,7 @@ export async function execute_near(
console.log("Upgrading contract"); console.log("Upgrading contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on near") throw new Error("RecoverChainId not supported on near");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
break; break;
@ -191,18 +191,18 @@ export async function execute_near(
impossible(payload); impossible(payload);
} }
let key = nearAPI.utils.KeyPair.fromString(n.key); let key = KeyPair.fromString(n.key);
let keyStore = new nearAPI.keyStores.InMemoryKeyStore(); let keyStore = new InMemoryKeyStore();
keyStore.setKey(n.networkId, n.deployerAccount, key); keyStore.setKey(n.networkId, n.deployerAccount, key);
let near = await nearAPI.connect({ let near = await connect({
keyStore, keyStore,
networkId: n.networkId, networkId: n.networkId,
nodeUrl: n.rpc, nodeUrl: n.rpc,
headers: {},
}); });
let nearAccount = new Account(near.connection, n.deployerAccount);
let nearAccount = new nearAPI.Account(near.connection, n.deployerAccount);
console.log("submitting vaa the first time"); console.log("submitting vaa the first time");
let result1 = await nearAccount.functionCall({ let result1 = await nearAccount.functionCall({

View File

@ -1,8 +1,8 @@
import { ChainName } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import { ChainName } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import { homedir } from "os";
import { config } from "dotenv";
const os = require("os"); config({ path: `${homedir()}/.wormhole/.env` });
const dir = os.homedir();
require("dotenv").config({ path: `${dir}/.wormhole/.env` });
function get_env_var(env: string): string | undefined { function get_env_var(env: string): string | undefined {
const v = process.env[env]; const v = process.env[env];

View File

@ -4,12 +4,12 @@ import { getSigningCosmWasmClient } from "@sei-js/core";
import { impossible, Payload } from "./vaa"; import { impossible, Payload } from "./vaa";
import { NETWORKS } from "./networks"; import { NETWORKS } from "./networks";
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
export async function execute_sei( export async function execute_sei(
payload: Payload, payload: Payload,
vaa: Buffer, vaa: Buffer,
network: "MAINNET" | "TESTNET" | "DEVNET", network: "MAINNET" | "TESTNET" | "DEVNET"
) { ) {
let chain = "sei"; let chain = "sei";
let n = NETWORKS[network][chain]; let n = NETWORKS[network][chain];
@ -35,7 +35,7 @@ export async function execute_sei(
console.log("Upgrading core contract"); console.log("Upgrading core contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on sei") throw new Error("RecoverChainId not supported on sei");
default: default:
impossible(payload); impossible(payload);
} }
@ -58,7 +58,7 @@ export async function execute_sei(
console.log("Upgrading contract"); console.log("Upgrading contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on sei") throw new Error("RecoverChainId not supported on sei");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
break; break;
@ -81,7 +81,7 @@ export async function execute_sei(
console.log("Upgrading contract"); console.log("Upgrading contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on sei") throw new Error("RecoverChainId not supported on sei");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
break; break;
@ -103,7 +103,9 @@ export async function execute_sei(
execute_msg = impossible(payload); execute_msg = impossible(payload);
} }
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(n.key, { prefix: "sei" }); const wallet = await DirectSecp256k1HdWallet.fromMnemonic(n.key, {
prefix: "sei",
});
const [account] = await wallet.getAccounts(); const [account] = await wallet.getAccounts();
const client = await getSigningCosmWasmClient(n.rpc, wallet); const client = await getSigningCosmWasmClient(n.rpc, wallet);
const fee = calculateFee(300000, "0.1usei"); const fee = calculateFee(300000, "0.1usei");

View File

@ -2,27 +2,27 @@ import * as web3s from "@solana/web3.js";
import { NETWORKS } from "./networks"; import { NETWORKS } from "./networks";
import { impossible, Payload, VAA } from "./vaa"; import { impossible, Payload, VAA } from "./vaa";
import base58 from "bs58"; import base58 from "bs58";
import { postVaaSolanaWithRetry } from "@certusone/wormhole-sdk/lib/cjs/solana"; import { postVaaSolanaWithRetry } from "@certusone/wormhole-sdk/lib/esm/solana";
import { import {
CHAINS, CHAINS,
CONTRACTS, CONTRACTS,
SolanaChainName, SolanaChainName,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import { import {
createUpgradeContractInstruction as createWormholeUpgradeContractInstruction, createUpgradeContractInstruction as createWormholeUpgradeContractInstruction,
createUpgradeGuardianSetInstruction, createUpgradeGuardianSetInstruction,
} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; } from "@certusone/wormhole-sdk/lib/esm/solana/wormhole";
import { import {
createCompleteTransferNativeInstruction, createCompleteTransferNativeInstruction,
createCompleteTransferWrappedInstruction, createCompleteTransferWrappedInstruction,
createCreateWrappedInstruction, createCreateWrappedInstruction,
createRegisterChainInstruction as createTokenBridgeRegisterChainInstruction, createRegisterChainInstruction as createTokenBridgeRegisterChainInstruction,
createUpgradeContractInstruction as createTokenBridgeUpgradeContractInstruction, createUpgradeContractInstruction as createTokenBridgeUpgradeContractInstruction,
} from "@certusone/wormhole-sdk/lib/cjs/solana/tokenBridge"; } from "@certusone/wormhole-sdk/lib/esm/solana/tokenBridge";
import { import {
createRegisterChainInstruction as createNFTBridgeRegisterChainInstruction, createRegisterChainInstruction as createNFTBridgeRegisterChainInstruction,
createUpgradeContractInstruction as createNFTBridgeUpgradeContractInstruction, createUpgradeContractInstruction as createNFTBridgeUpgradeContractInstruction,
} from "@certusone/wormhole-sdk/lib/cjs/solana/nftBridge"; } from "@certusone/wormhole-sdk/lib/esm/solana/nftBridge";
export async function execute_solana( export async function execute_solana(
v: VAA<Payload>, v: VAA<Payload>,
@ -67,7 +67,7 @@ export async function execute_solana(
); );
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on solana") throw new Error("RecoverChainId not supported on solana");
default: default:
ix = impossible(v.payload); ix = impossible(v.payload);
} }
@ -87,7 +87,7 @@ export async function execute_solana(
); );
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on solana") throw new Error("RecoverChainId not supported on solana");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
ix = createNFTBridgeRegisterChainInstruction( ix = createNFTBridgeRegisterChainInstruction(
@ -120,7 +120,7 @@ export async function execute_solana(
); );
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on solana") throw new Error("RecoverChainId not supported on solana");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
ix = createTokenBridgeRegisterChainInstruction( ix = createTokenBridgeRegisterChainInstruction(
@ -177,7 +177,7 @@ export async function execute_solana(
}, },
bridgeId, bridgeId,
from.publicKey, from.publicKey,
vaa, vaa
); );
// Then do the actual thing // Then do the actual thing

View File

@ -1,16 +1,16 @@
import { parseAttestMetaVaa } from "@certusone/wormhole-sdk/lib/cjs/vaa/tokenBridge"; import { parseAttestMetaVaa } from "@certusone/wormhole-sdk/lib/esm/vaa/tokenBridge";
import { getForeignAssetSui } from "@certusone/wormhole-sdk/lib/cjs/token_bridge/getForeignAsset"; import { getForeignAssetSui } from "@certusone/wormhole-sdk/lib/esm/token_bridge/getForeignAsset";
import { import {
createWrappedOnSui, createWrappedOnSui,
createWrappedOnSuiPrepare, createWrappedOnSuiPrepare,
} from "@certusone/wormhole-sdk/lib/cjs/token_bridge/createWrapped"; } from "@certusone/wormhole-sdk/lib/esm/token_bridge/createWrapped";
import { assertChain } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import { assertChain } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import { getWrappedCoinType } from "@certusone/wormhole-sdk/lib/cjs/sui"; import { getWrappedCoinType } from "@certusone/wormhole-sdk/lib/esm/sui";
import { import {
CHAIN_ID_SUI, CHAIN_ID_SUI,
CHAIN_ID_TO_NAME, CHAIN_ID_TO_NAME,
CONTRACTS, CONTRACTS,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
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 { Network } from "../utils";
import { Payload, impossible } from "../vaa"; import { Payload, impossible } from "../vaa";

View File

@ -12,7 +12,7 @@ import axios from "axios";
import { import {
CONTRACTS, CONTRACTS,
TerraChainName, TerraChainName,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
export async function execute_terra( export async function execute_terra(
payload: Payload, payload: Payload,

View File

@ -8,7 +8,7 @@ import {
import { fromUint8Array } from "js-base64"; import { fromUint8Array } from "js-base64";
import { impossible, Payload } from "./vaa"; import { impossible, Payload } from "./vaa";
import { NETWORKS } from "./networks"; import { NETWORKS } from "./networks";
import { CONTRACTS } from "@certusone/wormhole-sdk/lib/cjs/utils/consts"; import { CONTRACTS } from "@certusone/wormhole-sdk/lib/esm/utils/consts";
export async function execute_xpla( export async function execute_xpla(
payload: Payload, payload: Payload,
@ -49,7 +49,7 @@ export async function execute_xpla(
console.log("Upgrading core contract"); console.log("Upgrading core contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on XPLA") throw new Error("RecoverChainId not supported on XPLA");
default: default:
impossible(payload); impossible(payload);
} }
@ -72,7 +72,7 @@ export async function execute_xpla(
console.log("Upgrading contract"); console.log("Upgrading contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on XPLA") throw new Error("RecoverChainId not supported on XPLA");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
break; break;
@ -95,7 +95,7 @@ export async function execute_xpla(
console.log("Upgrading contract"); console.log("Upgrading contract");
break; break;
case "RecoverChainId": case "RecoverChainId":
throw new Error("RecoverChainId not supported on XPLA") throw new Error("RecoverChainId not supported on XPLA");
case "RegisterChain": case "RegisterChain":
console.log("Registering chain"); console.log("Registering chain");
break; break;

View File

@ -1,73 +1,12 @@
{ {
"compilerOptions": { "compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */ "incremental": true,
"target": "es2019",
/* Basic Options */ "module": "commonjs",
"incremental": true /* Enable incremental compilation */, "outDir": "./build",
"target": "es2019" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, "moduleResolution": "node",
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, "esModuleInterop": true,
// "lib": [], /* Specify library files to be included in the compilation. */ "forceConsistentCasingInFileNames": true
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./build" /* Redirect output structure to the directory. */,
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
"downlevelIteration": true /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */,
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": false /* Enable all strict type-checking options. */,
"noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */,
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
/* Module Resolution Options */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}, },
"include": ["src"] "include": ["src"]
} }