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
## 0.0.3
### Changed
Build a minified bundle
## 0.0.2
### Changed

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "@wormhole-foundation/wormhole-cli",
"version": "0.0.2",
"version": "0.0.3",
"description": "CLI for Wormhole related activities",
"homepage": "https://wormhole.com",
"bin": {
@ -11,8 +11,10 @@
],
"repository": "https://github.com/certusone/wormhole/tree/main/clients/js",
"scripts": {
"start": "ts-node main.ts",
"build": "tsc",
"start": "npm run build && node ./build/main.js",
"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"
},
"author": "Wormhole Contributors",
@ -24,7 +26,7 @@
],
"dependencies": {
"@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",
"@injectivelabs/networks": "^1.10.7",
"@injectivelabs/sdk-ts": "^1.10.47",
@ -45,11 +47,12 @@
"buffer-layout": "^1.2.2",
"config": "^3.3.7",
"dotenv": "^10.0.0",
"esbuild": "0.17.18",
"ethers": "^5.6.8",
"js-base64": "^3.6.1",
"near-api-js": "^0.45.1",
"near-seed-phrase": "^0.2.0",
"yargs": "^17.0.1"
"yargs": "^17.7.2"
},
"devDependencies": {
"@truffle/hdwallet-provider": "^2.0.15",
@ -57,7 +60,6 @@
"@types/bs58": "^4.0.1",
"@types/yargs": "^17.0.2",
"copy-dir": "^1.3.0",
"ts-node": "^10.7.0",
"typescript": "^4.6"
}
}

View File

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

View File

@ -3,7 +3,11 @@ import { NETWORKS } from "./networks";
import { impossible, Payload } from "./vaa";
import { sha3_256 } from "js-sha3";
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(
payload: Payload,
@ -23,66 +27,115 @@ export async function execute_aptos(
case "Core":
contract = contract ?? CONTRACTS[network][chain]["core"];
if (contract === undefined) {
throw Error("core bridge contract is undefined")
throw Error("core bridge contract is undefined");
}
switch (payload.type) {
case "GuardianSetUpgrade":
console.log("Submitting new guardian set")
await callEntryFunc(network, rpc, `${contract}::guardian_set_upgrade`, "submit_vaa_entry", [], [bcsVAA]);
break
console.log("Submitting new guardian set");
await callEntryFunc(
network,
rpc,
`${contract}::guardian_set_upgrade`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "ContractUpgrade":
console.log("Upgrading core contract")
await callEntryFunc(network, rpc, `${contract}::contract_upgrade`, "submit_vaa_entry", [], [bcsVAA]);
break
console.log("Upgrading core contract");
await callEntryFunc(
network,
rpc,
`${contract}::contract_upgrade`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on aptos")
throw new Error("RecoverChainId not supported on aptos");
default:
impossible(payload)
impossible(payload);
}
break
break;
case "NFTBridge":
contract = contract ?? CONTRACTS[network][chain]["nft_bridge"];
if (contract === undefined) {
throw Error("nft bridge contract is undefined")
throw Error("nft bridge contract is undefined");
}
switch (payload.type) {
case "ContractUpgrade":
console.log("Upgrading contract")
await callEntryFunc(network, rpc, `${contract}::contract_upgrade`, "submit_vaa_entry", [], [bcsVAA]);
break
console.log("Upgrading contract");
await callEntryFunc(
network,
rpc,
`${contract}::contract_upgrade`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on aptos")
throw new Error("RecoverChainId not supported on aptos");
case "RegisterChain":
console.log("Registering chain")
await callEntryFunc(network, rpc, `${contract}::register_chain`, "submit_vaa_entry", [], [bcsVAA]);
break
console.log("Registering chain");
await callEntryFunc(
network,
rpc,
`${contract}::register_chain`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "Transfer": {
console.log("Completing transfer")
await callEntryFunc(network, rpc, `${contract}::complete_transfer`, "submit_vaa_entry", [], [bcsVAA]);
break
console.log("Completing transfer");
await callEntryFunc(
network,
rpc,
`${contract}::complete_transfer`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
}
default:
impossible(payload)
impossible(payload);
}
break
break;
case "TokenBridge":
contract = contract ?? CONTRACTS[network][chain]["token_bridge"];
if (contract === undefined) {
throw Error("token bridge contract is undefined")
throw Error("token bridge contract is undefined");
}
switch (payload.type) {
case "ContractUpgrade":
console.log("Upgrading contract")
await callEntryFunc(network, rpc, `${contract}::contract_upgrade`, "submit_vaa_entry", [], [bcsVAA]);
break
console.log("Upgrading contract");
await callEntryFunc(
network,
rpc,
`${contract}::contract_upgrade`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on aptos")
throw new Error("RecoverChainId not supported on aptos");
case "RegisterChain":
console.log("Registering chain")
await callEntryFunc(network, rpc, `${contract}::register_chain`, "submit_vaa_entry", [], [bcsVAA]);
break
console.log("Registering chain");
await callEntryFunc(
network,
rpc,
`${contract}::register_chain`,
"submit_vaa_entry",
[],
[bcsVAA]
);
break;
case "AttestMeta": {
console.log("Creating wrapped token")
console.log("Creating wrapped token");
// Deploying a wrapped asset requires two transactions:
// 1. Publish a new module under a resource account that defines a type T
// 2. Initialise a new coin with that type T
@ -91,9 +144,16 @@ export async function execute_aptos(
//
// Tx 1.
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) {
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
@ -105,63 +165,102 @@ export async function execute_aptos(
const tokenAddress = payload.tokenAddress;
const tokenChain = payload.tokenChain;
assertChain(tokenChain);
let wrappedContract = deriveWrappedAssetAddress(hex(contract), tokenChain, hex(tokenAddress));
let wrappedContract = deriveWrappedAssetAddress(
hex(contract),
tokenChain,
hex(tokenAddress)
);
// Tx 2.
console.log(`Deploying resource account ${wrappedContract}`);
let token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString(`${wrappedContract}::coin::T`));
await callEntryFunc(network, rpc, `${contract}::wrapped`, "create_wrapped_coin", [token], [bcsVAA]);
let token = new TxnBuilderTypes.TypeTagStruct(
TxnBuilderTypes.StructTag.fromString(`${wrappedContract}::coin::T`)
);
await callEntryFunc(
network,
rpc,
`${contract}::wrapped`,
"create_wrapped_coin",
[token],
[bcsVAA]
);
break
break;
}
case "Transfer": {
console.log("Completing transfer")
console.log("Completing transfer");
// TODO: only handles wrapped assets for now
const tokenAddress = payload.tokenAddress;
const tokenChain = payload.tokenChain;
assertChain(tokenChain);
let wrappedContract = deriveWrappedAssetAddress(hex(contract), tokenChain, 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
let wrappedContract = deriveWrappedAssetAddress(
hex(contract),
tokenChain,
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":
throw Error("Can't complete payload 3 transfer from CLI")
throw Error("Can't complete payload 3 transfer from CLI");
default:
impossible(payload)
break
impossible(payload);
break;
}
break
break;
default:
impossible(payload)
impossible(payload);
}
}
export function deriveWrappedAssetAddress(
token_bridge_address: Uint8Array, // 32 bytes
origin_chain: ChainId,
origin_address: Uint8Array, // 32 bytes
origin_address: Uint8Array // 32 bytes
): string {
let chain: Buffer = Buffer.alloc(2);
chain.writeUInt16BE(origin_chain);
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
let DERIVE_RESOURCE_ACCOUNT_SCHEME = Buffer.alloc(1);
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(
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
let DERIVE_RESOURCE_ACCOUNT_SCHEME = Buffer.alloc(1);
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(
@ -170,7 +269,7 @@ export async function callEntryFunc(
module: string,
func: string,
ty_args: BCS.Seq<TxnBuilderTypes.TypeTag>,
args: BCS.Seq<BCS.Bytes>,
args: BCS.Seq<BCS.Bytes>
) {
let key: string | undefined = NETWORKS[network]["aptos"].key;
if (key === undefined) {
@ -179,7 +278,7 @@ export async function callEntryFunc(
const accountFrom = new AptosAccount(new Uint8Array(Buffer.from(key, "hex")));
let client: AptosClient;
// 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);
} else {
client = new AptosClient(NETWORKS[network]["aptos"].rpc);
@ -190,12 +289,7 @@ export async function callEntryFunc(
]);
const txPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
TxnBuilderTypes.EntryFunction.natural(
module,
func,
ty_args,
args
)
TxnBuilderTypes.EntryFunction.natural(module, func, ty_args, args)
);
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(100), //price per unit gas TODO(csongor): we should get this dynamically
BigInt(Math.floor(Date.now() / 1000) + 10),
new TxnBuilderTypes.ChainId(chainId),
new TxnBuilderTypes.ChainId(chainId)
);
// simulate transaction before submitting
@ -226,5 +320,8 @@ export async function callEntryFunc(
// strip the 0x prefix from a hex string
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,
coalesceChainId,
CONTRACTS,
} from "@certusone/wormhole-sdk/lib/cjs/utils/consts";
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
import { BCS, FaucetClient } from "aptos";
import { spawnSync } from "child_process";
import fs from "fs";
import sha3 from "js-sha3";
import { homedir } from "os";
import yargs from "yargs";
import {
callEntryFunc,
@ -39,9 +40,9 @@ interface PackageBCS {
codeHash: Uint8Array;
}
exports.command = "aptos";
exports.desc = "Aptos utilities";
exports.builder = function (y: typeof yargs) {
export const command = "aptos";
export const desc = "Aptos utilities";
export const builder = function (y: typeof yargs) {
return (
y
// NOTE: there's no init-nft-bridge, because the native module initialiser
@ -452,9 +453,7 @@ exports.builder = function (y: typeof yargs) {
},
(argv) => {
checkBinary("aptos", README_URL);
const os = require("os");
const dir = os.homedir();
const cmd = `cd ${dir} && aptos node run-local-testnet --with-faucet --force-restart --assume-yes`;
const cmd = `cd ${homedir()} && aptos node run-local-testnet --with-faucet --force-restart --assume-yes`;
runCommand(cmd, argv["validator-args"]);
}
)
@ -524,3 +523,5 @@ function serializePackage(p: Package): PackageBCS {
codeHash,
};
}
export const handler = (argv) => {};

View File

@ -1,21 +1,21 @@
import yargs from "yargs";
import {
CHAINS,
assertChain,
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>";
exports.desc =
export const command = "chain-id <chain>";
export const desc =
"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", {
describe: "Chain to query",
type: "string",
choices: Object.keys(CHAINS),
});
};
exports.handler = (argv) => {
export const handler = (argv) => {
assertChain(argv["chain"]);
console.log(coalesceChainId(argv["chain"]));
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,10 @@
import yargs from "yargs";
import { deploy_near, upgrade_near } from "../near";
// Near utilities
exports.command = "near";
exports.desc = "NEAR utilities";
exports.builder = function (y: typeof yargs) {
const near = require("../near");
export const command = "near";
export const desc = "NEAR utilities";
export const builder = function (y: typeof yargs) {
return y
.option("module", {
alias: "m",
@ -55,7 +55,7 @@ exports.builder = function (y: typeof yargs) {
});
},
async (argv) => {
await near.upgrade_near(argv);
await upgrade_near(argv);
}
)
.command(
@ -68,7 +68,9 @@ exports.builder = function (y: typeof yargs) {
});
},
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 { parse, vaaDigest } from "../vaa";
exports.command = "parse <vaa>";
exports.desc = "Parse a VAA (can be in either hex or base64 format)";
exports.builder = (y: typeof yargs) => {
export const command = "parse <vaa>";
export const desc = "Parse a VAA (can be in either hex or base64 format)";
export const builder = (y: typeof yargs) => {
return y.positional("vaa", {
describe: "vaa",
type: "string",
});
};
exports.handler = (argv) => {
export const handler = (argv) => {
let buf: Buffer;
try {
buf = Buffer.from(String(argv.vaa), "hex");

View File

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

View File

@ -1,13 +1,13 @@
import yargs from "yargs";
import {
CHAINS,
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";
exports.command = "rpc <network> <chain>";
exports.desc = "Print RPC address";
exports.builder = (y: typeof yargs) => {
export const command = "rpc <network> <chain>";
export const desc = "Print RPC address";
export const builder = (y: typeof yargs) => {
return y
.positional("network", {
describe: "network",
@ -20,7 +20,7 @@ exports.builder = (y: typeof yargs) => {
choices: Object.keys(CHAINS),
});
};
exports.handler = async (argv) => {
export const handler = async (argv) => {
assertChain(argv["chain"]);
const network = argv.network.toUpperCase();
if (network !== "MAINNET" && network !== "TESTNET" && network !== "DEVNET") {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,30 +1,33 @@
declare module 'elliptic' {
export interface BN {
length: number;
negative: number;
words: Uint8Array;
toString(format: string?): string;
}
declare module "elliptic" {
export interface BN {
length: number;
negative: number;
words: Uint8Array;
toString(format?: string): string;
}
export interface Point {
x: BN;
y: BN;
}
export interface Point {
x: BN;
y: BN;
}
export interface KeyPair {
getPrivate(): BN;
getPublic(): Point;
sign(message: Buffer, options: any): {
r: BN,
s: BN,
recoveryParam: number
};
}
export interface KeyPair {
getPrivate(): BN;
getPublic(): Point;
sign(
message: Buffer,
options: any
): {
r: BN;
s: BN;
recoveryParam: number;
};
}
export class ec {
constructor(curveName: string);
genKeyPair(): KeyPair;
keyFromPrivate(priv: any, enc?: any): KeyPair;
keyFromPublic(priv: any, enc: any): KeyPair;
}
export class ec {
constructor(curveName: string);
genKeyPair(): KeyPair;
keyFromPrivate(priv: any, enc?: any): KeyPair;
keyFromPublic(priv: any, enc: any): KeyPair;
}
}

View File

@ -1,13 +1,23 @@
import { ethers } from "ethers"
import { NETWORKS } from "./networks"
import { encode, Encoding, impossible, Payload, typeWidth } from "./vaa"
import { ethers } from "ethers";
import { NETWORKS } from "./networks";
import { encode, Encoding, impossible, Payload, typeWidth } from "./vaa";
import axios from "axios";
import * as celo from "@celo-tools/celo-ethers-wrapper";
import { solidityKeccak256 } from "ethers/lib/utils"
import { CHAINS, CONTRACTS, Contracts, EVMChainName } from "@certusone/wormhole-sdk/lib/cjs/utils/consts";
import { BridgeImplementation__factory, Implementation__factory, NFTBridgeImplementation__factory } from "@certusone/wormhole-sdk/lib/cjs/ethers-contracts";
import { solidityKeccak256 } from "ethers/lib/utils";
import {
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(
network: "MAINNET" | "TESTNET" | "DEVNET",
@ -16,28 +26,32 @@ export async function query_contract_evm(
contract_address: string | undefined,
_rpc: string | undefined
): Promise<object> {
let n = NETWORKS[network][chain]
let n = NETWORKS[network][chain];
let rpc: string | undefined = _rpc ?? n.rpc;
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) {
case "Core":
contract_address = contract_address ? contract_address : contracts.core;
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)
result.address = contract_address
result.currentGuardianSetIndex = await core.getCurrentGuardianSetIndex()
let guardianSetsPromise = Promise.all([...Array(result.currentGuardianSetIndex + 1).keys()].map((i) => core.getGuardianSet(i)))
const core = Implementation__factory.connect(contract_address, provider);
result.address = contract_address;
result.currentGuardianSetIndex = await core.getCurrentGuardianSetIndex();
let guardianSetsPromise = Promise.all(
[...Array(result.currentGuardianSetIndex + 1).keys()].map((i) =>
core.getGuardianSet(i)
)
);
let [
guardianSetExpiry,
chainId,
@ -47,7 +61,7 @@ export async function query_contract_evm(
governanceContract,
messageFee,
implementationSlot,
guardianSets
guardianSets,
] = await Promise.all([
core.getGuardianSetExpiry(),
core.chainId(),
@ -57,36 +71,47 @@ export async function query_contract_evm(
core.governanceContract(),
core.messageFee(),
getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]),
guardianSetsPromise
])
result.guardianSetExpiry = guardianSetExpiry
result.chainId = chainId
result.evmChainId = evmChainId.toString()
result.isFork = isFork
result.governanceChainId = governanceChainId
result.governanceContract = governanceContract
result.messageFee = messageFee
result.implementation = implementationSlot[0]
result.isInitialized = await core.isInitialized(result.implementation)
result.guardianSet = {}
guardianSetsPromise,
]);
result.guardianSetExpiry = guardianSetExpiry;
result.chainId = chainId;
result.evmChainId = evmChainId.toString();
result.isFork = isFork;
result.governanceChainId = governanceChainId;
result.governanceContract = governanceContract;
result.messageFee = messageFee;
result.implementation = implementationSlot[0];
result.isInitialized = await core.isInitialized(result.implementation);
result.guardianSet = {};
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":
contract_address = contract_address ? contract_address : contracts.token_bridge;
contract_address = contract_address
? contract_address
: contracts.token_bridge;
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)
result.address = contract_address
const tb = BridgeImplementation__factory.connect(
contract_address,
provider
);
result.address = contract_address;
const registrationsPromise = Promise.all(
Object.entries(CHAINS)
.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 [
wormhole,
implementationSlotTb,
@ -98,7 +123,7 @@ export async function query_contract_evm(
governanceChainIdTb,
governanceContractTb,
WETH,
registrations
registrations,
] = await Promise.all([
tb.wormhole(),
getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]),
@ -110,37 +135,45 @@ export async function query_contract_evm(
tb.governanceChainId(),
tb.governanceContract(),
tb.WETH(),
registrationsPromise
])
result.wormhole = wormhole
result.implementation = implementationSlotTb[0]
result.isInitialized = await tb.isInitialized(result.implementation)
result.tokenImplementation = tokenImplementation
result.chainId = chainIdTb
result.finality = finality
result.evmChainId = evmChainIdTb.toString()
result.isFork = isForkTb
result.governanceChainId = governanceChainIdTb
result.governanceContract = governanceContractTb
result.WETH = WETH
result.registrations = {}
registrationsPromise,
]);
result.wormhole = wormhole;
result.implementation = implementationSlotTb[0];
result.isInitialized = await tb.isInitialized(result.implementation);
result.tokenImplementation = tokenImplementation;
result.chainId = chainIdTb;
result.finality = finality;
result.evmChainId = evmChainIdTb.toString();
result.isFork = isForkTb;
result.governanceChainId = governanceChainIdTb;
result.governanceContract = governanceContractTb;
result.WETH = WETH;
result.registrations = {};
for (let [c_name, c] of registrations) {
result.registrations[c_name] = c
result.registrations[c_name] = c;
}
break
break;
case "NFTBridge":
contract_address = contract_address ? contract_address : contracts.nft_bridge;
contract_address = contract_address
? contract_address
: contracts.nft_bridge;
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)
result.address = contract_address
const nb = NFTBridgeImplementation__factory.connect(
contract_address,
provider
);
result.address = contract_address;
const registrationsPromiseNb = Promise.all(
Object.entries(CHAINS)
.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 [
wormholeNb,
implementationSlotNb,
@ -151,7 +184,7 @@ export async function query_contract_evm(
isForkNb,
governanceChainIdNb,
governanceContractNb,
registrationsNb
registrationsNb,
] = await Promise.all([
nb.wormhole(),
getStorageAt(rpc, contract_address, _IMPLEMENTATION_SLOT, ["address"]),
@ -162,29 +195,29 @@ export async function query_contract_evm(
maybeUnsupported(nb.isFork()),
nb.governanceChainId(),
nb.governanceContract(),
registrationsPromiseNb
])
result.wormhole = wormholeNb
result.implementation = implementationSlotNb[0]
result.isInitialized = await nb.isInitialized(result.implementation)
result.tokenImplementation = tokenImplementationNb
result.chainId = chainIdNb
result.finality = finalityNb
result.evmChainId = evmChainIdNb.toString()
result.isFork = isForkNb
result.governanceChainId = governanceChainIdNb
result.governanceContract = governanceContractNb
result.registrations = {}
registrationsPromiseNb,
]);
result.wormhole = wormholeNb;
result.implementation = implementationSlotNb[0];
result.isInitialized = await nb.isInitialized(result.implementation);
result.tokenImplementation = tokenImplementationNb;
result.chainId = chainIdNb;
result.finality = finalityNb;
result.evmChainId = evmChainIdNb.toString();
result.isFork = isForkNb;
result.governanceChainId = governanceChainIdNb;
result.governanceContract = governanceContractNb;
result.registrations = {};
for (let [c_name, c] of registrationsNb) {
result.registrations[c_name] = c
result.registrations[c_name] = c;
}
break
break;
default:
impossible(module)
impossible(module);
}
return result
return result;
}
export async function getImplementation(
@ -194,29 +227,35 @@ export async function getImplementation(
contract_address: string | undefined,
_rpc: string | undefined
): Promise<ethers.BigNumber> {
let n = NETWORKS[network][chain]
let n = NETWORKS[network][chain];
let rpc: string | undefined = _rpc ?? n.rpc;
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) {
case "Core":
contract_address = contract_address ? contract_address : contracts.core;
break
break;
case "TokenBridge":
contract_address = contract_address ? contract_address : contracts.token_bridge;
break
contract_address = contract_address
? contract_address
: contracts.token_bridge;
break;
case "NFTBridge":
contract_address = contract_address ? contract_address : contracts.nft_bridge;
break
contract_address = contract_address
? contract_address
: contracts.nft_bridge;
break;
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(
@ -227,35 +266,35 @@ export async function execute_evm(
contract_address: string | undefined,
_rpc: string | undefined
) {
let n = NETWORKS[network][chain]
let n = NETWORKS[network][chain];
let rpc: string | undefined = _rpc ?? n.rpc;
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) {
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 signer: ethers.Wallet;
if (chain === "celo") {
provider = new celo.CeloProvider(rpc)
await provider.ready
signer = new celo.CeloWallet(key, provider)
provider = new celo.CeloProvider(rpc);
await provider.ready;
signer = new celo.CeloWallet(key, provider);
} else {
provider = new ethers.providers.JsonRpcProvider(rpc)
signer = new ethers.Wallet(key, provider)
provider = new ethers.providers.JsonRpcProvider(rpc);
signer = new ethers.Wallet(key, provider);
}
// Here we apply a set of chain-specific overrides.
// NOTE: some of these might have only been tested on mainnet. If it fails in
// testnet (or devnet), they might require additional guards
let overrides: ethers.Overrides = {}
let overrides: ethers.Overrides = {};
if (chain === "karura" || chain == "acala") {
overrides = await getKaruraGasParams(n.rpc)
overrides = await getKaruraGasParams(n.rpc);
} else if (chain === "polygon") {
let feeData = await provider.getFeeData();
overrides = {
@ -263,105 +302,128 @@ export async function execute_evm(
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas?.mul(50) || undefined,
};
} else if (chain === "klaytn" || chain === "fantom") {
overrides = { gasPrice: (await signer.getGasPrice()).toString() }
overrides = { gasPrice: (await signer.getGasPrice()).toString() };
}
switch (payload.module) {
case "Core":
contract_address = contract_address ? contract_address : contracts.core;
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 cb = c.attach(contract_address)
let c = new Implementation__factory(signer);
let cb = c.attach(contract_address);
switch (payload.type) {
case "GuardianSetUpgrade":
console.log("Submitting new guardian set")
console.log("Hash: " + (await cb.submitNewGuardianSet(vaa, overrides)).hash)
break
console.log("Submitting new guardian set");
console.log(
"Hash: " + (await cb.submitNewGuardianSet(vaa, overrides)).hash
);
break;
case "ContractUpgrade":
console.log("Upgrading core contract")
console.log("Hash: " + (await cb.submitContractUpgrade(vaa, overrides)).hash)
break
console.log("Upgrading core contract");
console.log(
"Hash: " + (await cb.submitContractUpgrade(vaa, overrides)).hash
);
break;
case "RecoverChainId":
console.log("Recovering chain ID")
console.log("Hash: " + (await cb.submitRecoverChainId(vaa, overrides)).hash)
break
console.log("Recovering chain ID");
console.log(
"Hash: " + (await cb.submitRecoverChainId(vaa, overrides)).hash
);
break;
default:
impossible(payload)
impossible(payload);
}
break
break;
case "NFTBridge":
contract_address = contract_address ? contract_address : contracts.nft_bridge;
contract_address = contract_address
? contract_address
: contracts.nft_bridge;
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 nb = n.attach(contract_address)
let n = new NFTBridgeImplementation__factory(signer);
let nb = n.attach(contract_address);
switch (payload.type) {
case "ContractUpgrade":
console.log("Upgrading contract")
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")
break
console.log("Upgrading contract");
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"
);
break;
case "RecoverChainId":
console.log("Recovering chain ID")
console.log("Hash: " + (await nb.submitRecoverChainId(vaa, overrides)).hash)
break
console.log("Recovering chain ID");
console.log(
"Hash: " + (await nb.submitRecoverChainId(vaa, overrides)).hash
);
break;
case "RegisterChain":
console.log("Registering chain")
console.log("Hash: " + (await nb.registerChain(vaa, overrides)).hash)
break
console.log("Registering chain");
console.log("Hash: " + (await nb.registerChain(vaa, overrides)).hash);
break;
case "Transfer":
console.log("Completing transfer")
console.log("Hash: " + (await nb.completeTransfer(vaa, overrides)).hash)
break
console.log("Completing transfer");
console.log(
"Hash: " + (await nb.completeTransfer(vaa, overrides)).hash
);
break;
default:
impossible(payload)
impossible(payload);
}
break
break;
case "TokenBridge":
contract_address = contract_address ? contract_address : contracts.token_bridge;
contract_address = contract_address
? contract_address
: contracts.token_bridge;
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 tb = t.attach(contract_address)
let t = new BridgeImplementation__factory(signer);
let tb = t.attach(contract_address);
switch (payload.type) {
case "ContractUpgrade":
console.log("Upgrading contract")
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")
break
console.log("Upgrading contract");
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"
);
break;
case "RecoverChainId":
console.log("Recovering chain ID")
console.log("Hash: " + (await tb.submitRecoverChainId(vaa, overrides)).hash)
break
console.log("Recovering chain ID");
console.log(
"Hash: " + (await tb.submitRecoverChainId(vaa, overrides)).hash
);
break;
case "RegisterChain":
console.log("Registering chain")
console.log("Hash: " + (await tb.registerChain(vaa, overrides)).hash)
break
console.log("Registering chain");
console.log("Hash: " + (await tb.registerChain(vaa, overrides)).hash);
break;
case "Transfer":
console.log("Completing transfer")
console.log("Hash: " + (await tb.completeTransfer(vaa, overrides)).hash)
break
console.log("Completing transfer");
console.log(
"Hash: " + (await tb.completeTransfer(vaa, overrides)).hash
);
break;
case "AttestMeta":
console.log("Creating wrapped token")
console.log("Hash: " + (await tb.createWrapped(vaa, overrides)).hash)
break
console.log("Creating wrapped token");
console.log("Hash: " + (await tb.createWrapped(vaa, overrides)).hash);
break;
case "TransferWithPayload":
console.log("Completing transfer with payload")
console.log("Hash: " + (await tb.completeTransferWithPayload(vaa, overrides)).hash)
break
console.log("Completing transfer with payload");
console.log(
"Hash: " +
(await tb.completeTransferWithPayload(vaa, overrides)).hash
);
break;
default:
impossible(payload)
break
impossible(payload);
break;
}
break
break;
default:
impossible(payload)
impossible(payload);
}
}
@ -392,39 +454,65 @@ export async function hijack_evm(
guardian_addresses: string[],
new_guardian_set_index: number | undefined
): Promise<void> {
const GUARDIAN_SETS_SLOT = 0x02
const GUARDIAN_SET_INDEX_SLOT = 0x3
const GUARDIAN_SETS_SLOT = 0x02;
const GUARDIAN_SET_INDEX_SLOT = 0x3;
const provider = new ethers.providers.JsonRpcProvider(rpc)
const core = Implementation__factory.connect(contract_address, provider)
let guardianSetIndex: number
let guardianSetExpiry: number
[guardianSetIndex, guardianSetExpiry] = await getStorageAt(rpc, contract_address, GUARDIAN_SET_INDEX_SLOT, ["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])
const provider = new ethers.providers.JsonRpcProvider(rpc);
const core = Implementation__factory.connect(contract_address, provider);
let guardianSetIndex: number;
let guardianSetExpiry: number;
[guardianSetIndex, guardianSetExpiry] = await getStorageAt(
rpc,
contract_address,
GUARDIAN_SET_INDEX_SLOT,
["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) {
await setStorageAt(rpc, contract_address, GUARDIAN_SET_INDEX_SLOT, ["uint32", "uint32"], [new_guardian_set_index, guardianSetExpiry])
guardianSetIndex = await core.getCurrentGuardianSetIndex()
await setStorageAt(
rpc,
contract_address,
GUARDIAN_SET_INDEX_SLOT,
["uint32", "uint32"],
[new_guardian_set_index, guardianSetExpiry]
);
guardianSetIndex = await core.getCurrentGuardianSetIndex();
if (new_guardian_set_index !== guardianSetIndex) {
throw Error("Failed to update guardian set index.")
throw Error("Failed to update guardian set index.");
} 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)
console.log(`Writing new set of guardians into set ${guardianSetIndex}...`)
const addresses_slot = computeMappingElemSlot(
GUARDIAN_SETS_SLOT,
guardianSetIndex
);
console.log(`Writing new set of guardians into set ${guardianSetIndex}...`);
guardian_addresses.forEach(async (address, i) => {
await setStorageAt(rpc, contract_address, computeArrayElemSlot(addresses_slot, i), ["address"], [address])
})
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.")
await setStorageAt(
rpc,
contract_address,
computeArrayElemSlot(addresses_slot, i),
["address"],
[address]
);
});
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<{
@ -461,9 +549,9 @@ async function getKaruraGasParams(rpc: string): Promise<{
//
// [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...
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 offset the index of the element to compute the storage slot for
*/
export function computeArrayElemSlot(array_slot: StorageSlotish, offset: number): StorageSlot {
return ethers.BigNumber.from(solidityKeccak256(["bytes"], [array_slot])).add(offset)
export function computeArrayElemSlot(
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 key the key to compute the storage slot for
*/
export function computeMappingElemSlot(map_slot: StorageSlotish, key: any): StorageSlot {
const slot_preimage = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [key, map_slot])
return ethers.BigNumber.from(solidityKeccak256(["bytes"], [slot_preimage]))
export function computeMappingElemSlot(
map_slot: StorageSlotish,
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)
*/
async function getStorageAt(rpc: string, contract_address: string, storage_slot: StorageSlotish, types: Encoding[]): Promise<any[]> {
const total = types.map((typ) => typeWidth(typ)).reduce((x, y) => (x + y))
async function getStorageAt(
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) {
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 =
await (new ethers.providers.JsonRpcProvider(rpc).getStorageAt(contract_address, storage_slot))
let val = ethers.BigNumber.from(string_val)
let ret: any[] = []
const string_val: string = await new ethers.providers.JsonRpcProvider(
rpc
).getStorageAt(contract_address, storage_slot);
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
types.forEach((typ) => {
const padded = ethers.utils.defaultAbiCoder.encode(["uint256"], [val])
ret.push(ethers.utils.defaultAbiCoder.decode([typ], padded)[0])
val = val.shr(typeWidth(typ) * 8)
})
return ret
const padded = ethers.utils.defaultAbiCoder.encode(["uint256"], [val]);
ret.push(ethers.utils.defaultAbiCoder.decode([typ], padded)[0]);
val = val.shr(typeWidth(typ) * 8);
});
return ret;
}
/**
@ -542,7 +649,13 @@ async function getStorageAt(rpc: string, contract_address: string, storage_slot:
*
* @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
// is stored at the rightmost bytes.
//
@ -550,42 +663,51 @@ export async function setStorageAt(rpc: string, contract_address: string, storag
// uint32 a
// uint32 b
// will be stored as 0x...b...a
const _values = values.reverse()
const _types = types.reverse()
const total = _types.map((typ) => typeWidth(typ)).reduce((x, y) => (x + y))
const _values = values.reverse();
const _types = types.reverse();
const total = _types.map((typ) => typeWidth(typ)).reduce((x, y) => x + y);
// ensure that the types fit into a slot
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) {
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
// 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
const slot = ethers.utils.defaultAbiCoder.encode(["uint256"], [storage_slot])
console.log(`slot ${slot} := ${val}`)
const slot = ethers.utils.defaultAbiCoder.encode(["uint256"], [storage_slot]);
console.log(`slot ${slot} := ${val}`);
return (await axios.post(rpc, {
id: 0,
jsonrpc: "2.0",
method: "hardhat_setStorageAt",
params: [
contract_address,
slot,
val,
],
})).data
return (
await axios.post(rpc, {
id: 0,
jsonrpc: "2.0",
method: "hardhat_setStorageAt",
params: [contract_address, slot, val],
})
).data;
}
async function maybeUnsupported<T>(query: Promise<T>): Promise<T | "unsupported"> {
async function maybeUnsupported<T>(
query: Promise<T>
): Promise<T | "unsupported"> {
try {
return await query
return await query;
} catch (e) {
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 {
ChainRestAuthApi,

View File

@ -10,17 +10,47 @@
// for lack of a better way to stop this, we patch the console.info function to
// drop that particular message...
// </sigh>
const info = console.info;
const infoTemp = console.info;
console.info = function (x: string) {
if (x != "secp256k1 unavailable, reverting to browser version") {
info(x);
infoTemp(x);
}
};
import yargs from "yargs";
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))
.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()
.demandCommand().argv;

View File

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

View File

@ -4,12 +4,12 @@ import { getSigningCosmWasmClient } from "@sei-js/core";
import { impossible, Payload } from "./vaa";
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(
payload: Payload,
vaa: Buffer,
network: "MAINNET" | "TESTNET" | "DEVNET",
network: "MAINNET" | "TESTNET" | "DEVNET"
) {
let chain = "sei";
let n = NETWORKS[network][chain];
@ -35,7 +35,7 @@ export async function execute_sei(
console.log("Upgrading core contract");
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on sei")
throw new Error("RecoverChainId not supported on sei");
default:
impossible(payload);
}
@ -58,7 +58,7 @@ export async function execute_sei(
console.log("Upgrading contract");
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on sei")
throw new Error("RecoverChainId not supported on sei");
case "RegisterChain":
console.log("Registering chain");
break;
@ -81,7 +81,7 @@ export async function execute_sei(
console.log("Upgrading contract");
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on sei")
throw new Error("RecoverChainId not supported on sei");
case "RegisterChain":
console.log("Registering chain");
break;
@ -102,9 +102,11 @@ export async function execute_sei(
target_contract = impossible(payload);
execute_msg = impossible(payload);
}
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(n.key, { prefix: "sei" });
const [ account ] = await wallet.getAccounts();
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(n.key, {
prefix: "sei",
});
const [account] = await wallet.getAccounts();
const client = await getSigningCosmWasmClient(n.rpc, wallet);
const fee = calculateFee(300000, "0.1usei");
const result = await client.execute(

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ import {
import { fromUint8Array } from "js-base64";
import { impossible, Payload } from "./vaa";
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(
payload: Payload,
@ -49,7 +49,7 @@ export async function execute_xpla(
console.log("Upgrading core contract");
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on XPLA")
throw new Error("RecoverChainId not supported on XPLA");
default:
impossible(payload);
}
@ -72,7 +72,7 @@ export async function execute_xpla(
console.log("Upgrading contract");
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on XPLA")
throw new Error("RecoverChainId not supported on XPLA");
case "RegisterChain":
console.log("Registering chain");
break;
@ -95,7 +95,7 @@ export async function execute_xpla(
console.log("Upgrading contract");
break;
case "RecoverChainId":
throw new Error("RecoverChainId not supported on XPLA")
throw new Error("RecoverChainId not supported on XPLA");
case "RegisterChain":
console.log("Registering chain");
break;

View File

@ -1,73 +1,12 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
"incremental": true /* Enable incremental compilation */,
"target": "es2019" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
// "lib": [], /* Specify library files to be included in the compilation. */
// "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. */
"incremental": true,
"target": "es2019",
"module": "commonjs",
"outDir": "./build",
"moduleResolution": "node",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"]
}