clients/js: formatting only change (prettier)
Change-Id: I0b8805e0a577f0ef8757a5468c43fcb1083c0825
This commit is contained in:
parent
a6f75f1aef
commit
338e6f2648
|
@ -4,9 +4,20 @@ import yargs from "yargs";
|
||||||
import { hideBin } from "yargs/helpers";
|
import { hideBin } from "yargs/helpers";
|
||||||
|
|
||||||
import { Bech32, fromBech32, toHex } from "@cosmjs/encoding";
|
import { Bech32, fromBech32, toHex } from "@cosmjs/encoding";
|
||||||
import { isTerraChain, assertEVMChain, CONTRACTS, setDefaultWasm } from "@certusone/wormhole-sdk";
|
import {
|
||||||
|
isTerraChain,
|
||||||
|
assertEVMChain,
|
||||||
|
CONTRACTS,
|
||||||
|
setDefaultWasm,
|
||||||
|
} from "@certusone/wormhole-sdk";
|
||||||
import { execute_solana } from "./solana";
|
import { execute_solana } from "./solana";
|
||||||
import { execute_evm, getImplementation, hijack_evm, query_contract_evm, setStorageAt } from "./evm";
|
import {
|
||||||
|
execute_evm,
|
||||||
|
getImplementation,
|
||||||
|
hijack_evm,
|
||||||
|
query_contract_evm,
|
||||||
|
setStorageAt,
|
||||||
|
} from "./evm";
|
||||||
import { execute_terra } from "./terra";
|
import { execute_terra } from "./terra";
|
||||||
import * as vaa from "./vaa";
|
import * as vaa from "./vaa";
|
||||||
import { impossible, Payload, serialiseVAA, VAA } from "./vaa";
|
import { impossible, Payload, serialiseVAA, VAA } from "./vaa";
|
||||||
|
@ -100,7 +111,10 @@ yargs(hideBin(process.argv))
|
||||||
type: "RegisterChain",
|
type: "RegisterChain",
|
||||||
chain: 0,
|
chain: 0,
|
||||||
emitterChain: toChainId(argv["chain"]),
|
emitterChain: toChainId(argv["chain"]),
|
||||||
emitterAddress: parseAddress(argv["chain"], argv["contract-address"]),
|
emitterAddress: parseAddress(
|
||||||
|
argv["chain"],
|
||||||
|
argv["contract-address"]
|
||||||
|
),
|
||||||
};
|
};
|
||||||
let v = makeVAA(
|
let v = makeVAA(
|
||||||
GOVERNANCE_CHAIN,
|
GOVERNANCE_CHAIN,
|
||||||
|
@ -148,7 +162,10 @@ yargs(hideBin(process.argv))
|
||||||
module,
|
module,
|
||||||
type: "ContractUpgrade",
|
type: "ContractUpgrade",
|
||||||
chain: toChainId(argv["chain"]),
|
chain: toChainId(argv["chain"]),
|
||||||
address: parseCodeAddress(argv["chain"], argv["contract-address"]),
|
address: parseCodeAddress(
|
||||||
|
argv["chain"],
|
||||||
|
argv["contract-address"]
|
||||||
|
),
|
||||||
};
|
};
|
||||||
let v = makeVAA(
|
let v = makeVAA(
|
||||||
GOVERNANCE_CHAIN,
|
GOVERNANCE_CHAIN,
|
||||||
|
@ -179,35 +196,46 @@ yargs(hideBin(process.argv))
|
||||||
async (argv) => {
|
async (argv) => {
|
||||||
let buf: Buffer;
|
let buf: Buffer;
|
||||||
try {
|
try {
|
||||||
buf = Buffer.from(String(argv.vaa), "hex")
|
buf = Buffer.from(String(argv.vaa), "hex");
|
||||||
if (buf.length == 0) {
|
if (buf.length == 0) {
|
||||||
throw Error("Couldn't parse VAA as hex")
|
throw Error("Couldn't parse VAA as hex");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
buf = Buffer.from(String(argv.vaa), "base64")
|
buf = Buffer.from(String(argv.vaa), "base64");
|
||||||
if (buf.length == 0) {
|
if (buf.length == 0) {
|
||||||
throw Error("Couldn't parse VAA as base64 or hex")
|
throw Error("Couldn't parse VAA as base64 or hex");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const parsed_vaa = vaa.parse(buf);
|
const parsed_vaa = vaa.parse(buf);
|
||||||
let parsed_vaa_with_digest = parsed_vaa;
|
let parsed_vaa_with_digest = parsed_vaa;
|
||||||
parsed_vaa_with_digest['digest'] = vaa.vaaDigest(parsed_vaa);
|
parsed_vaa_with_digest["digest"] = vaa.vaaDigest(parsed_vaa);
|
||||||
console.log(parsed_vaa_with_digest);
|
console.log(parsed_vaa_with_digest);
|
||||||
})
|
}
|
||||||
.command("recover <digest> <signature>", "Recover an address from a signature", (yargs) => {
|
)
|
||||||
|
.command(
|
||||||
|
"recover <digest> <signature>",
|
||||||
|
"Recover an address from a signature",
|
||||||
|
(yargs) => {
|
||||||
return yargs
|
return yargs
|
||||||
.positional("digest", {
|
.positional("digest", {
|
||||||
describe: "digest",
|
describe: "digest",
|
||||||
type: "string"
|
type: "string",
|
||||||
})
|
})
|
||||||
.positional("signature", {
|
.positional("signature", {
|
||||||
describe: "signature",
|
describe: "signature",
|
||||||
type: "string"
|
type: "string",
|
||||||
});
|
});
|
||||||
}, async (argv) => {
|
},
|
||||||
console.log(ethers.utils.recoverAddress(hex(argv["digest"]), hex(argv["signature"])))
|
async (argv) => {
|
||||||
})
|
console.log(
|
||||||
.command("contract <network> <chain> <module>", "Print contract address", (yargs) => {
|
ethers.utils.recoverAddress(hex(argv["digest"]), hex(argv["signature"]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.command(
|
||||||
|
"contract <network> <chain> <module>",
|
||||||
|
"Print contract address",
|
||||||
|
(yargs) => {
|
||||||
return yargs
|
return yargs
|
||||||
.positional("network", {
|
.positional("network", {
|
||||||
describe: "network",
|
describe: "network",
|
||||||
|
@ -223,10 +251,11 @@ yargs(hideBin(process.argv))
|
||||||
describe: "Module to query",
|
describe: "Module to query",
|
||||||
type: "string",
|
type: "string",
|
||||||
choices: ["Core", "NFTBridge", "TokenBridge"],
|
choices: ["Core", "NFTBridge", "TokenBridge"],
|
||||||
})
|
});
|
||||||
}, async (argv) => {
|
},
|
||||||
assertChain(argv["chain"])
|
async (argv) => {
|
||||||
assertEVMChain(argv["chain"])
|
assertChain(argv["chain"]);
|
||||||
|
assertEVMChain(argv["chain"]);
|
||||||
const network = argv.network.toUpperCase();
|
const network = argv.network.toUpperCase();
|
||||||
if (
|
if (
|
||||||
network !== "MAINNET" &&
|
network !== "MAINNET" &&
|
||||||
|
@ -235,25 +264,26 @@ yargs(hideBin(process.argv))
|
||||||
) {
|
) {
|
||||||
throw Error(`Unknown network: ${network}`);
|
throw Error(`Unknown network: ${network}`);
|
||||||
}
|
}
|
||||||
let module = argv["module"] as
|
let module = argv["module"] as "Core" | "NFTBridge" | "TokenBridge";
|
||||||
| "Core"
|
|
||||||
| "NFTBridge"
|
|
||||||
| "TokenBridge";
|
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case "Core":
|
case "Core":
|
||||||
console.log(CONTRACTS[network][argv["chain"]]["core"])
|
console.log(CONTRACTS[network][argv["chain"]]["core"]);
|
||||||
break;
|
break;
|
||||||
case "NFTBridge":
|
case "NFTBridge":
|
||||||
console.log(CONTRACTS[network][argv["chain"]]["nft_bridge"])
|
console.log(CONTRACTS[network][argv["chain"]]["nft_bridge"]);
|
||||||
break;
|
break;
|
||||||
case "TokenBridge":
|
case "TokenBridge":
|
||||||
console.log(CONTRACTS[network][argv["chain"]]["token_bridge"])
|
console.log(CONTRACTS[network][argv["chain"]]["token_bridge"]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
impossible(module)
|
impossible(module);
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.command("rpc <network> <chain>", "Print RPC address", (yargs) => {
|
)
|
||||||
|
.command(
|
||||||
|
"rpc <network> <chain>",
|
||||||
|
"Print RPC address",
|
||||||
|
(yargs) => {
|
||||||
return yargs
|
return yargs
|
||||||
.positional("network", {
|
.positional("network", {
|
||||||
describe: "network",
|
describe: "network",
|
||||||
|
@ -264,10 +294,11 @@ yargs(hideBin(process.argv))
|
||||||
describe: "Chain to query",
|
describe: "Chain to query",
|
||||||
type: "string",
|
type: "string",
|
||||||
choices: Object.keys(CHAINS),
|
choices: Object.keys(CHAINS),
|
||||||
})
|
});
|
||||||
}, async (argv) => {
|
},
|
||||||
assertChain(argv["chain"])
|
async (argv) => {
|
||||||
assertEVMChain(argv["chain"])
|
assertChain(argv["chain"]);
|
||||||
|
assertEVMChain(argv["chain"]);
|
||||||
const network = argv.network.toUpperCase();
|
const network = argv.network.toUpperCase();
|
||||||
if (
|
if (
|
||||||
network !== "MAINNET" &&
|
network !== "MAINNET" &&
|
||||||
|
@ -276,24 +307,38 @@ yargs(hideBin(process.argv))
|
||||||
) {
|
) {
|
||||||
throw Error(`Unknown network: ${network}`);
|
throw Error(`Unknown network: ${network}`);
|
||||||
}
|
}
|
||||||
console.log(NETWORKS[network][argv["chain"]].rpc)
|
console.log(NETWORKS[network][argv["chain"]].rpc);
|
||||||
})
|
}
|
||||||
|
)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Evm utilities
|
// Evm utilities
|
||||||
.command("evm", "EVM utilites", (yargs) => {
|
.command(
|
||||||
|
"evm",
|
||||||
|
"EVM utilites",
|
||||||
|
(yargs) => {
|
||||||
return yargs
|
return yargs
|
||||||
.option("rpc", {
|
.option("rpc", {
|
||||||
describe: "RPC endpoint",
|
describe: "RPC endpoint",
|
||||||
type: "string",
|
type: "string",
|
||||||
required: false
|
required: false,
|
||||||
})
|
})
|
||||||
.command("address-from-secret <secret>", "Compute a 20 byte eth address from a 32 byte private key", (yargs) => {
|
.command(
|
||||||
return yargs
|
"address-from-secret <secret>",
|
||||||
.positional("secret", { type: "string", describe: "Secret key (32 bytes)" })
|
"Compute a 20 byte eth address from a 32 byte private key",
|
||||||
}, (argv) => {
|
(yargs) => {
|
||||||
console.log(ethers.utils.computeAddress(argv["secret"]))
|
return yargs.positional("secret", {
|
||||||
})
|
type: "string",
|
||||||
.command("storage-update", "Update a storage slot on an EVM fork during testing (anvil or hardhat)", (yargs) => {
|
describe: "Secret key (32 bytes)",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(argv) => {
|
||||||
|
console.log(ethers.utils.computeAddress(argv["secret"]));
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.command(
|
||||||
|
"storage-update",
|
||||||
|
"Update a storage slot on an EVM fork during testing (anvil or hardhat)",
|
||||||
|
(yargs) => {
|
||||||
return yargs
|
return yargs
|
||||||
.option("contract-address", {
|
.option("contract-address", {
|
||||||
alias: "a",
|
alias: "a",
|
||||||
|
@ -313,16 +358,30 @@ yargs(hideBin(process.argv))
|
||||||
type: "string",
|
type: "string",
|
||||||
required: true,
|
required: true,
|
||||||
});
|
});
|
||||||
}, async (argv) => {
|
},
|
||||||
const result = await setStorageAt(argv["rpc"], evm_address(argv["contract-address"]), argv["storage-slot"], ["uint256"], [argv["value"]]);
|
async (argv) => {
|
||||||
|
const result = await setStorageAt(
|
||||||
|
argv["rpc"],
|
||||||
|
evm_address(argv["contract-address"]),
|
||||||
|
argv["storage-slot"],
|
||||||
|
["uint256"],
|
||||||
|
[argv["value"]]
|
||||||
|
);
|
||||||
console.log(result);
|
console.log(result);
|
||||||
})
|
|
||||||
.command("chains", "Return all EVM chains",
|
|
||||||
async (_) => {
|
|
||||||
console.log(Object.values(CHAINS).map(id => toChainName(id)).filter(name => isEVMChain(name)).join(" "))
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.command("info", "Query info about the on-chain state of the contract", (yargs) => {
|
.command("chains", "Return all EVM chains", async (_) => {
|
||||||
|
console.log(
|
||||||
|
Object.values(CHAINS)
|
||||||
|
.map((id) => toChainName(id))
|
||||||
|
.filter((name) => isEVMChain(name))
|
||||||
|
.join(" ")
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.command(
|
||||||
|
"info",
|
||||||
|
"Query info about the on-chain state of the contract",
|
||||||
|
(yargs) => {
|
||||||
return yargs
|
return yargs
|
||||||
.option("chain", {
|
.option("chain", {
|
||||||
alias: "c",
|
alias: "c",
|
||||||
|
@ -358,9 +417,10 @@ yargs(hideBin(process.argv))
|
||||||
default: false,
|
default: false,
|
||||||
required: false,
|
required: false,
|
||||||
});
|
});
|
||||||
}, async (argv) => {
|
},
|
||||||
assertChain(argv["chain"])
|
async (argv) => {
|
||||||
assertEVMChain(argv["chain"])
|
assertChain(argv["chain"]);
|
||||||
|
assertEVMChain(argv["chain"]);
|
||||||
const network = argv.network.toUpperCase();
|
const network = argv.network.toUpperCase();
|
||||||
if (
|
if (
|
||||||
network !== "MAINNET" &&
|
network !== "MAINNET" &&
|
||||||
|
@ -369,18 +429,39 @@ yargs(hideBin(process.argv))
|
||||||
) {
|
) {
|
||||||
throw Error(`Unknown network: ${network}`);
|
throw Error(`Unknown network: ${network}`);
|
||||||
}
|
}
|
||||||
let module = argv["module"] as
|
let module = argv["module"] as "Core" | "NFTBridge" | "TokenBridge";
|
||||||
| "Core"
|
let rpc = argv["rpc"] ?? NETWORKS[network][argv["chain"]].rpc;
|
||||||
| "NFTBridge"
|
|
||||||
| "TokenBridge";
|
|
||||||
let rpc = argv["rpc"] ?? NETWORKS[network][argv["chain"]].rpc
|
|
||||||
if (argv["implementation-only"]) {
|
if (argv["implementation-only"]) {
|
||||||
console.log(await getImplementation(network, argv["chain"], module, argv["contract-address"], rpc))
|
console.log(
|
||||||
|
await getImplementation(
|
||||||
|
network,
|
||||||
|
argv["chain"],
|
||||||
|
module,
|
||||||
|
argv["contract-address"],
|
||||||
|
rpc
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log(JSON.stringify(await query_contract_evm(network, argv["chain"], module, argv["contract-address"], rpc), null, 2))
|
console.log(
|
||||||
|
JSON.stringify(
|
||||||
|
await query_contract_evm(
|
||||||
|
network,
|
||||||
|
argv["chain"],
|
||||||
|
module,
|
||||||
|
argv["contract-address"],
|
||||||
|
rpc
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.command("hijack", "Override the guardian set of the core bridge contract during testing (anvil or hardhat)", (yargs) => {
|
)
|
||||||
|
.command(
|
||||||
|
"hijack",
|
||||||
|
"Override the guardian set of the core bridge contract during testing (anvil or hardhat)",
|
||||||
|
(yargs) => {
|
||||||
return yargs
|
return yargs
|
||||||
.option("core-contract-address", {
|
.option("core-contract-address", {
|
||||||
alias: "a",
|
alias: "a",
|
||||||
|
@ -397,14 +478,22 @@ yargs(hideBin(process.argv))
|
||||||
.option("guardian-set-index", {
|
.option("guardian-set-index", {
|
||||||
alias: "i",
|
alias: "i",
|
||||||
required: false,
|
required: false,
|
||||||
describe: "New guardian set index (if unspecified, default to overriding the current index)",
|
describe:
|
||||||
type: "number"
|
"New guardian set index (if unspecified, default to overriding the current index)",
|
||||||
|
type: "number",
|
||||||
});
|
});
|
||||||
}, async (argv) => {
|
},
|
||||||
const guardian_addresses = argv["guardian-address"].split(",")
|
async (argv) => {
|
||||||
let rpc = argv["rpc"] ?? NETWORKS.DEVNET.ethereum.rpc
|
const guardian_addresses = argv["guardian-address"].split(",");
|
||||||
await hijack_evm(rpc, argv["core-contract-address"], guardian_addresses, argv["guardian-set-index"])
|
let rpc = argv["rpc"] ?? NETWORKS.DEVNET.ethereum.rpc;
|
||||||
})
|
await hijack_evm(
|
||||||
|
rpc,
|
||||||
|
argv["core-contract-address"],
|
||||||
|
guardian_addresses,
|
||||||
|
argv["guardian-set-index"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
(_) => {
|
(_) => {
|
||||||
yargs.showHelp();
|
yargs.showHelp();
|
||||||
|
@ -445,9 +534,10 @@ yargs(hideBin(process.argv))
|
||||||
.option("rpc", {
|
.option("rpc", {
|
||||||
describe: "RPC endpoint",
|
describe: "RPC endpoint",
|
||||||
type: "string",
|
type: "string",
|
||||||
required: false
|
required: false,
|
||||||
})
|
});
|
||||||
}, async (argv) => {
|
},
|
||||||
|
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);
|
||||||
|
@ -504,7 +594,14 @@ yargs(hideBin(process.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)) {
|
||||||
await execute_evm(parsed_vaa.payload, buf, network, chain, argv["contract-address"], argv["rpc"]);
|
await execute_evm(
|
||||||
|
parsed_vaa.payload,
|
||||||
|
buf,
|
||||||
|
network,
|
||||||
|
chain,
|
||||||
|
argv["contract-address"],
|
||||||
|
argv["rpc"]
|
||||||
|
);
|
||||||
} else if (isTerraChain(chain)) {
|
} else if (isTerraChain(chain)) {
|
||||||
await execute_terra(parsed_vaa.payload, buf, network, chain);
|
await execute_terra(parsed_vaa.payload, buf, network, chain);
|
||||||
} else if (chain === "solana") {
|
} else if (chain === "solana") {
|
||||||
|
@ -530,44 +627,44 @@ yargs(hideBin(process.argv))
|
||||||
).argv;
|
).argv;
|
||||||
|
|
||||||
function hex(x: string): string {
|
function hex(x: string): string {
|
||||||
return ethers.utils.hexlify(x, { allowMissingPrefix: true })
|
return ethers.utils.hexlify(x, { allowMissingPrefix: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function evm_address(x: string): string {
|
function evm_address(x: string): string {
|
||||||
return hex(x).substring(2).padStart(64, "0")
|
return hex(x).substring(2).padStart(64, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseAddress(chain: ChainName, address: string): string {
|
function parseAddress(chain: ChainName, address: string): string {
|
||||||
if (chain === "unset") {
|
if (chain === "unset") {
|
||||||
throw Error("Chain unset")
|
throw Error("Chain unset");
|
||||||
} else if (isEVMChain(chain)) {
|
} else if (isEVMChain(chain)) {
|
||||||
return "0x" + evm_address(address)
|
return "0x" + evm_address(address);
|
||||||
} else if (isTerraChain(chain)) {
|
} else if (isTerraChain(chain)) {
|
||||||
return "0x" + toHex(fromBech32(address).data).padStart(64, "0")
|
return "0x" + toHex(fromBech32(address).data).padStart(64, "0");
|
||||||
} else if (chain === "solana") {
|
} else if (chain === "solana") {
|
||||||
return "0x" + toHex(base58.decode(address)).padStart(64, "0")
|
return "0x" + toHex(base58.decode(address)).padStart(64, "0");
|
||||||
} else if (chain === "algorand") {
|
} else if (chain === "algorand") {
|
||||||
// TODO: is there a better native format for algorand?
|
// TODO: is there a better native format for algorand?
|
||||||
return "0x" + evm_address(address)
|
return "0x" + evm_address(address);
|
||||||
} else if (chain === "near") {
|
} else if (chain === "near") {
|
||||||
throw Error("NEAR is not supported yet")
|
throw Error("NEAR is not supported yet");
|
||||||
} else if (chain === "injective") {
|
} else if (chain === "injective") {
|
||||||
throw Error("INJECTIVE is not supported yet");
|
throw Error("INJECTIVE is not supported yet");
|
||||||
} 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") {
|
||||||
throw Error("SUI is not supported yet")
|
throw Error("SUI is not supported yet");
|
||||||
} else if (chain === "aptos") {
|
} else if (chain === "aptos") {
|
||||||
throw Error("APTOS is not supported yet")
|
throw Error("APTOS is not supported yet");
|
||||||
} else {
|
} else {
|
||||||
impossible(chain)
|
impossible(chain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCodeAddress(chain: ChainName, address: string): string {
|
function parseCodeAddress(chain: ChainName, address: string): string {
|
||||||
if (isTerraChain(chain)) {
|
if (isTerraChain(chain)) {
|
||||||
return "0x" + parseInt(address, 10).toString(16).padStart(64, "0")
|
return "0x" + parseInt(address, 10).toString(16).padStart(64, "0");
|
||||||
} else {
|
} else {
|
||||||
return parseAddress(chain, address)
|
return parseAddress(chain, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue