From 6309b321e8ff5cbd1122686a21bd5d499580c124 Mon Sep 17 00:00:00 2001 From: Paul Noel <35237584+panoel@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:30:14 +0000 Subject: [PATCH] ci: add github workflow with prettier checks for clients/js/src and sdk/js/src (#3176) * github: add prettier check for clients/js * github: update workflow to include sdk/js --- .github/workflows/build.yml | 8 + .prettierignore | 1 + clients/js/src/algorand.ts | 2 +- clients/js/src/chains/sei/submit.ts | 2 +- clients/js/src/chains/sui/submit.ts | 2 +- clients/js/src/chains/sui/utils.ts | 4 +- clients/js/src/cmds/generate.ts | 10 +- clients/js/src/cmds/status.ts | 29 +- clients/js/src/cmds/sui/setup.ts | 5 +- clients/js/src/doc.ts | 17 +- clients/js/src/emitter.ts | 2 +- clients/js/src/side-effects.ts | 6 +- clients/js/src/terra.ts | 2 +- clients/js/src/vaa.ts | 1637 +++++++++-------- clients/js/src/xpla.ts | 2 +- sdk/js/src/aptos/api/coreBridge.ts | 11 +- sdk/js/src/aptos/api/tokenBridge.ts | 32 +- sdk/js/src/bridge/parseSequenceFromLog.ts | 9 +- sdk/js/src/index.ts | 2 +- sdk/js/src/mock/governance.ts | 2 - .../src/relayer/__tests__/relay_provider.ts | 41 +- sdk/js/src/relayer/__tests__/utils/utils.ts | 92 +- sdk/js/src/relayer/relayer/helpers.ts | 2 +- sdk/js/src/relayer/relayer/send.ts | 2 +- sdk/js/src/relayer/structs.ts | 98 +- sdk/js/src/solana/wormhole/coder/events.ts | 4 +- sdk/js/src/solana/wormhole/coder/idl.ts | 192 +- sdk/js/src/solana/wormhole/coder/state.ts | 2 +- sdk/js/src/solana/wormhole/coder/types.ts | 18 +- .../wormhole/instructions/initialize.ts | 8 +- .../wormhole/instructions/verifySignature.ts | 9 +- sdk/js/src/utils/array.ts | 2 +- sdk/js/src/utils/consts.ts | 13 +- sdk/js/src/vaa/generic.ts | 10 +- 34 files changed, 1208 insertions(+), 1070 deletions(-) create mode 100644 .prettierignore diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c0d45880a..c9f1b8154 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -394,3 +394,11 @@ jobs: uses: actions/checkout@v2 - run: chmod 755 ./scripts/check-npm-package-scopes.sh - run: ./scripts/check-npm-package-scopes.sh + prettier: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16 + - run: npx prettier --check ./clients/js/src ./sdk/js/src diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..53ab73622 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +sdk/js/src/ethers-contracts \ No newline at end of file diff --git a/clients/js/src/algorand.ts b/clients/js/src/algorand.ts index 7cfb51b8d..e66ef2906 100644 --- a/clients/js/src/algorand.ts +++ b/clients/js/src/algorand.ts @@ -115,7 +115,7 @@ export async function execute_algorand( break; } case "WormholeRelayer": - throw Error("Wormhole Relayer not supported on Algorand"); + throw Error("Wormhole Relayer not supported on Algorand"); default: target_contract = impossible(payload); } diff --git a/clients/js/src/chains/sei/submit.ts b/clients/js/src/chains/sei/submit.ts index 351efa9b6..580675cea 100644 --- a/clients/js/src/chains/sei/submit.ts +++ b/clients/js/src/chains/sei/submit.ts @@ -120,7 +120,7 @@ export const submit = async ( break; } case "WormholeRelayer": - throw Error("Wormhole Relayer not supported on Sei"); + throw Error("Wormhole Relayer not supported on Sei"); default: target_contract = impossible(payload); execute_msg = impossible(payload); diff --git a/clients/js/src/chains/sui/submit.ts b/clients/js/src/chains/sui/submit.ts index 017a33934..061dce668 100644 --- a/clients/js/src/chains/sui/submit.ts +++ b/clients/js/src/chains/sui/submit.ts @@ -199,7 +199,7 @@ export const submit = async ( break; } case "WormholeRelayer": - throw Error("Wormhole Relayer not supported on Sui"); + throw Error("Wormhole Relayer not supported on Sui"); default: impossible(payload); } diff --git a/clients/js/src/chains/sui/utils.ts b/clients/js/src/chains/sui/utils.ts index bd4a9ca52..ec4d84a02 100644 --- a/clients/js/src/chains/sui/utils.ts +++ b/clients/js/src/chains/sui/utils.ts @@ -311,14 +311,14 @@ export const isSameType = (a: string, b: string) => { export const isSuiCreateEvent = < T extends NonNullable[number], - K extends Extract + K extends Extract, >( event: T ): event is K => event?.type === "created"; export const isSuiPublishEvent = < T extends NonNullable[number], - K extends Extract + K extends Extract, >( event: T ): event is K => event?.type === "published"; diff --git a/clients/js/src/cmds/generate.ts b/clients/js/src/cmds/generate.ts index 762b79156..5d6b6e0aa 100644 --- a/clients/js/src/cmds/generate.ts +++ b/clients/js/src/cmds/generate.ts @@ -82,8 +82,7 @@ export const builder = function (y: typeof yargs) { describe: "Module to register", choices: ["NFTBridge", "TokenBridge", "WormholeRelayer"], demandOption: true, - } as const) - , + } as const), (argv) => { const module = argv["module"]; assertChain(argv.chain); @@ -272,7 +271,7 @@ export const builder = function (y: typeof yargs) { describe: "Address of the delivery provider contract", type: "string", demandOption: true, - }) + }); }, (argv) => { assertChain(argv.chain); @@ -280,7 +279,10 @@ export const builder = function (y: typeof yargs) { module: "WormholeRelayer", type: "SetDefaultDeliveryProvider", chain: toChainId(argv["chain"]), - relayProviderAddress: parseAddress(argv["chain"], argv["delivery-provider-address"]) + relayProviderAddress: parseAddress( + argv["chain"], + argv["delivery-provider-address"] + ), }; let v = makeVAA( GOVERNANCE_CHAIN, diff --git a/clients/js/src/cmds/status.ts b/clients/js/src/cmds/status.ts index 18e31c59f..6e0c210af 100644 --- a/clients/js/src/cmds/status.ts +++ b/clients/js/src/cmds/status.ts @@ -2,12 +2,8 @@ import { CHAINS, ChainName, assertChain, - } from "@certusone/wormhole-sdk/lib/esm/utils/consts"; -import { - relayer, - Network -} from "@certusone/wormhole-sdk" +import { relayer, Network } from "@certusone/wormhole-sdk"; import yargs from "yargs"; import { CONTRACTS, NETWORKS } from "../consts"; import { assertNetwork } from "../utils"; @@ -15,7 +11,8 @@ import { impossible } from "../vaa"; import { ethers } from "ethers"; export const command = "status "; -export const desc = "Prints information about the automatic delivery initiated on the specified network, chain, and tx"; +export const desc = + "Prints information about the automatic delivery initiated on the specified network, chain, and tx"; export const builder = (y: typeof yargs) => y .positional("network", { @@ -40,8 +37,9 @@ export const handler = async ( assertNetwork(network); const chain = argv.chain; assertChain(chain); - - const addr = relayer.RELAYER_CONTRACTS[network][chain]?.wormholeRelayerAddress; + + const addr = + relayer.RELAYER_CONTRACTS[network][chain]?.wormholeRelayerAddress; if (!addr) { throw new Error(`Wormhole Relayer not deployed on ${chain} in ${network}`); } @@ -49,11 +47,20 @@ export const handler = async ( const sourceRPC = NETWORKS[network as Network][chain as ChainName].rpc; const sourceChainProvider = new ethers.providers.JsonRpcProvider(sourceRPC); const targetChainProviders = new Map(); - for(const key in NETWORKS[network]) { - targetChainProviders.set(key as ChainName, new ethers.providers.JsonRpcProvider(NETWORKS[network][key as ChainName].rpc)); + for (const key in NETWORKS[network]) { + targetChainProviders.set( + key as ChainName, + new ethers.providers.JsonRpcProvider( + NETWORKS[network][key as ChainName].rpc + ) + ); } - const info = await relayer.getWormholeRelayerInfo(chain, argv.tx, {environment: network, sourceChainProvider, targetChainProviders}); + const info = await relayer.getWormholeRelayerInfo(chain, argv.tx, { + environment: network, + sourceChainProvider, + targetChainProviders, + }); console.log(relayer.stringifyWormholeRelayerInfo(info)); }; diff --git a/clients/js/src/cmds/sui/setup.ts b/clients/js/src/cmds/sui/setup.ts index 380b99af9..4ad9c19bc 100644 --- a/clients/js/src/cmds/sui/setup.ts +++ b/clients/js/src/cmds/sui/setup.ts @@ -123,9 +123,8 @@ export const addSetupCommands: YargsAddCommandsFn = (y: typeof yargs) => // Get token bridge state object ID const tokenBridgeStateObjectId = getCreatedObjects( tokenBridgeInitRes - ).find((e) => - isSameType(e.type, `${tokenBridgePackageId}::state::State`) - )?.objectId; + ).find((e) => isSameType(e.type, `${tokenBridgePackageId}::state::State`)) + ?.objectId; if (!tokenBridgeStateObjectId) { throw new Error("Couldn't find token bridge state object ID."); } diff --git a/clients/js/src/doc.ts b/clients/js/src/doc.ts index fc95704a9..a009dd544 100644 --- a/clients/js/src/doc.ts +++ b/clients/js/src/doc.ts @@ -18,12 +18,11 @@ import * as sui from "./cmds/sui"; import * as verifyVaa from "./cmds/verifyVaa"; import * as status from "./cmds/status"; - const MD_TAG = ""; async function getHelpText(cmd: any): Promise { // Note that `yargs` is called as a function to produce a fresh copy. - // Otherwise the imported module is effectively a singleton where state from + // Otherwise the imported module is effectively a singleton where state from // other commands is accumulated from repeat calls. return await cmd.builder(yargs()).scriptName(`worm ${cmd.command}`).getHelp(); } @@ -41,14 +40,15 @@ async function getHelpText(cmd: any): Promise { submit, sui, verifyVaa, - status + status, ]; const helpOutputs: Buffer[] = []; for (const cmd of cmds) { const helpText = await getHelpText(cmd); - helpOutputs.push(Buffer.from(` + helpOutputs.push( + Buffer.from(`
${cmd.command} @@ -56,11 +56,10 @@ async function getHelpText(cmd: any): Promise { ${helpText} \`\`\`
-`)) +`) + ); } - - const f = fs.readFileSync("README.md"); const startIdx = f.indexOf(MD_TAG, 0); const stopIdx = f.indexOf(MD_TAG, startIdx + 1); @@ -68,7 +67,7 @@ ${helpText} const head = f.subarray(0, startIdx + MD_TAG.length); const tail = f.subarray(stopIdx, f.length); - const content = Buffer.concat([head, ...helpOutputs, tail]) + const content = Buffer.concat([head, ...helpOutputs, tail]); - fs.writeFileSync("README.md", content.toString()) + fs.writeFileSync("README.md", content.toString()); })(); diff --git a/clients/js/src/emitter.ts b/clients/js/src/emitter.ts index a8552d965..c2481941e 100644 --- a/clients/js/src/emitter.ts +++ b/clients/js/src/emitter.ts @@ -9,7 +9,7 @@ import { getEmitterAddressEth, getEmitterAddressNear, getEmitterAddressSolana, - getEmitterAddressTerra + getEmitterAddressTerra, } from "@certusone/wormhole-sdk/lib/esm/bridge/getEmitterAddress"; export async function getEmitterAddress( diff --git a/clients/js/src/side-effects.ts b/clients/js/src/side-effects.ts index 8a131c24d..37b688521 100644 --- a/clients/js/src/side-effects.ts +++ b/clients/js/src/side-effects.ts @@ -29,10 +29,10 @@ console.warn = function (x: string) { // // eslint-disable-next-line @typescript-eslint/no-redeclare interface BigInt { - /** Convert to BigInt to string form in JSON.stringify */ - toJSON: () => string; + /** Convert to BigInt to string form in JSON.stringify */ + toJSON: () => string; } // Without this JSON.stringify() blows up (BigInt.prototype as any).toJSON = function () { - return this.toString(); + return this.toString(); }; diff --git a/clients/js/src/terra.ts b/clients/js/src/terra.ts index 06d163715..0f3faac76 100644 --- a/clients/js/src/terra.ts +++ b/clients/js/src/terra.ts @@ -143,7 +143,7 @@ export async function execute_terra( break; } case "WormholeRelayer": - throw Error("Wormhole Relayer not supported on Terra"); + throw Error("Wormhole Relayer not supported on Terra"); default: target_contract = impossible(payload); execute_msg = impossible(payload); diff --git a/clients/js/src/vaa.ts b/clients/js/src/vaa.ts index 19391945e..08a4e6139 100644 --- a/clients/js/src/vaa.ts +++ b/clients/js/src/vaa.ts @@ -1,603 +1,642 @@ -import { Parser } from "binary-parser" -import * as elliptic from "elliptic" -import { BigNumber, ethers } from "ethers" -import { solidityKeccak256 } from "ethers/lib/utils" +import { Parser } from "binary-parser"; +import * as elliptic from "elliptic"; +import { BigNumber, ethers } from "ethers"; +import { solidityKeccak256 } from "ethers/lib/utils"; export interface Signature { - guardianSetIndex: number - signature: string + guardianSetIndex: number; + signature: string; } export interface VAA { - version: number - guardianSetIndex: number - signatures: Signature[] - timestamp: number - nonce: number - emitterChain: number - emitterAddress: string - sequence: bigint - consistencyLevel: number - payload: T + version: number; + guardianSetIndex: number; + signatures: Signature[]; + timestamp: number; + nonce: number; + emitterChain: number; + emitterAddress: string; + sequence: bigint; + consistencyLevel: number; + payload: T; } class P { - private parser: Parser - constructor(parser: Parser) { - this.parser = parser - } + private parser: Parser; + constructor(parser: Parser) { + this.parser = parser; + } - // Try to parse a buffer with a parser, and return null if it failed due to an - // assertion error. - parse(buffer: Buffer): T | null { - try { - let result = this.parser.parse(buffer) - delete result['end'] - return result - } catch (e: any) { - if (e.message?.includes("Assertion error")) { - return null - } else { - throw e - } - } + // Try to parse a buffer with a parser, and return null if it failed due to an + // assertion error. + parse(buffer: Buffer): T | null { + try { + let result = this.parser.parse(buffer); + delete result["end"]; + return result; + } catch (e: any) { + if (e.message?.includes("Assertion error")) { + return null; + } else { + throw e; + } } + } - or(other: P): P { - let p = new P(other.parser); - p.parse = (buffer: Buffer): T | U | null => { - return this.parse(buffer) ?? other.parse(buffer) - } - return p - } + or(other: P): P { + let p = new P(other.parser); + p.parse = (buffer: Buffer): T | U | null => { + return this.parse(buffer) ?? other.parse(buffer); + }; + return p; + } } export interface Other { - type: "Other", - hex: string, - ascii?: string + type: "Other"; + hex: string; + ascii?: string; } // All the different types of payloads export type Payload = - GuardianSetUpgrade - | CoreContractUpgrade - | PortalContractUpgrade<"TokenBridge"> - | PortalContractUpgrade<"NFTBridge"> - | PortalContractUpgrade<"WormholeRelayer"> - | PortalRegisterChain<"TokenBridge"> - | PortalRegisterChain<"NFTBridge"> - | PortalRegisterChain<"WormholeRelayer"> - | TokenBridgeTransfer - | TokenBridgeTransferWithPayload - | TokenBridgeAttestMeta - | NFTBridgeTransfer - | CoreContractRecoverChainId - | PortalContractRecoverChainId<"TokenBridge"> - | PortalContractRecoverChainId<"NFTBridge"> - | WormholeRelayerSetDefaultDeliveryProvider + | GuardianSetUpgrade + | CoreContractUpgrade + | PortalContractUpgrade<"TokenBridge"> + | PortalContractUpgrade<"NFTBridge"> + | PortalContractUpgrade<"WormholeRelayer"> + | PortalRegisterChain<"TokenBridge"> + | PortalRegisterChain<"NFTBridge"> + | PortalRegisterChain<"WormholeRelayer"> + | TokenBridgeTransfer + | TokenBridgeTransferWithPayload + | TokenBridgeAttestMeta + | NFTBridgeTransfer + | CoreContractRecoverChainId + | PortalContractRecoverChainId<"TokenBridge"> + | PortalContractRecoverChainId<"NFTBridge"> + | WormholeRelayerSetDefaultDeliveryProvider; export type ContractUpgrade = - CoreContractUpgrade - | PortalContractUpgrade<"TokenBridge"> - | PortalContractUpgrade<"NFTBridge"> - | PortalContractUpgrade<"WormholeRelayer"> + | CoreContractUpgrade + | PortalContractUpgrade<"TokenBridge"> + | PortalContractUpgrade<"NFTBridge"> + | PortalContractUpgrade<"WormholeRelayer">; export type RecoverChainId = - CoreContractRecoverChainId - | PortalContractRecoverChainId<"TokenBridge"> - | PortalContractRecoverChainId<"NFTBridge"> + | CoreContractRecoverChainId + | PortalContractRecoverChainId<"TokenBridge"> + | PortalContractRecoverChainId<"NFTBridge">; export function parse(buffer: Buffer): VAA { - const vaa = parseEnvelope(buffer) - const parser = guardianSetUpgradeParser - .or(coreContractUpgradeParser) - .or(portalContractUpgradeParser("TokenBridge")) - .or(portalContractUpgradeParser("NFTBridge")) - .or(portalContractUpgradeParser("WormholeRelayer")) - .or(portalRegisterChainParser("TokenBridge")) - .or(portalRegisterChainParser("NFTBridge")) - .or(portalRegisterChainParser("WormholeRelayer")) - .or(tokenBridgeTransferParser()) - .or(tokenBridgeTransferWithPayloadParser()) - .or(tokenBridgeAttestMetaParser()) - .or(nftBridgeTransferParser()) - .or(coreContractRecoverChainId()) - .or(portalContractRecoverChainId("TokenBridge")) - .or(portalContractRecoverChainId("NFTBridge")) - .or(wormholeRelayerSetDefaultDeliveryProvider()) - let payload : Payload | Other | null = parser.parse(vaa.payload) - if (payload === null) { - payload = {type: "Other", hex: Buffer.from(vaa.payload).toString("hex"), ascii: Buffer.from(vaa.payload).toString('utf8')} - } else { - delete (payload as any)['tokenURILength'] - } - var myVAA = { ...vaa, payload } + const vaa = parseEnvelope(buffer); + const parser = guardianSetUpgradeParser + .or(coreContractUpgradeParser) + .or(portalContractUpgradeParser("TokenBridge")) + .or(portalContractUpgradeParser("NFTBridge")) + .or(portalContractUpgradeParser("WormholeRelayer")) + .or(portalRegisterChainParser("TokenBridge")) + .or(portalRegisterChainParser("NFTBridge")) + .or(portalRegisterChainParser("WormholeRelayer")) + .or(tokenBridgeTransferParser()) + .or(tokenBridgeTransferWithPayloadParser()) + .or(tokenBridgeAttestMetaParser()) + .or(nftBridgeTransferParser()) + .or(coreContractRecoverChainId()) + .or(portalContractRecoverChainId("TokenBridge")) + .or(portalContractRecoverChainId("NFTBridge")) + .or(wormholeRelayerSetDefaultDeliveryProvider()); + let payload: Payload | Other | null = parser.parse(vaa.payload); + if (payload === null) { + payload = { + type: "Other", + hex: Buffer.from(vaa.payload).toString("hex"), + ascii: Buffer.from(vaa.payload).toString("utf8"), + }; + } else { + delete (payload as any)["tokenURILength"]; + } + var myVAA = { ...vaa, payload }; - return myVAA + return myVAA; } -export function assertKnownPayload(vaa: VAA): asserts vaa is VAA { - if (vaa.payload.type === "Other") { - throw Error(`Couldn't parse VAA payload: ${vaa.payload.hex}`); - } +export function assertKnownPayload( + vaa: VAA +): asserts vaa is VAA { + if (vaa.payload.type === "Other") { + throw Error(`Couldn't parse VAA payload: ${vaa.payload.hex}`); + } } // Parse the VAA envelope without looking into the payload. // If you want to parse the payload as well, use 'parse'. export function parseEnvelope(buffer: Buffer): VAA { - var vaa = vaaParser.parse(buffer) - delete vaa['end'] - delete vaa['signatureCount'] - vaa.payload = Buffer.from(vaa.payload) - return vaa + var vaa = vaaParser.parse(buffer); + delete vaa["end"]; + delete vaa["signatureCount"]; + vaa.payload = Buffer.from(vaa.payload); + return vaa; } // Parse a signature const signatureParser = new Parser() - .endianess("big") - .uint8("guardianSetIndex") - .array("signature", { - type: "uint8", - lengthInBytes: 65, - formatter: arr => Buffer.from(arr).toString("hex") - }) + .endianess("big") + .uint8("guardianSetIndex") + .array("signature", { + type: "uint8", + lengthInBytes: 65, + formatter: (arr) => Buffer.from(arr).toString("hex"), + }); function serialiseSignature(sig: Signature): string { - const body = [ - encode("uint8", sig.guardianSetIndex), - sig.signature - ] - return body.join("") + const body = [encode("uint8", sig.guardianSetIndex), sig.signature]; + return body.join(""); } // Parse a vaa envelope. The payload is returned as a byte array. const vaaParser = new Parser() - .endianess("big") - .uint8("version") - .uint32("guardianSetIndex") - .uint8("signatureCount") - .array("signatures", { - type: signatureParser, - length: "signatureCount" - }) - .uint32("timestamp") - .uint32("nonce") - .uint16("emitterChain") - .array("emitterAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: arr => "0x" + Buffer.from(arr).toString("hex") - }) - .uint64("sequence") - .uint8("consistencyLevel") - .array("payload", { - type: "uint8", - readUntil: "eof" - }) - .string("end", { - greedy: true, - assert: str => str === "" - }) + .endianess("big") + .uint8("version") + .uint32("guardianSetIndex") + .uint8("signatureCount") + .array("signatures", { + type: signatureParser, + length: "signatureCount", + }) + .uint32("timestamp") + .uint32("nonce") + .uint16("emitterChain") + .array("emitterAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .uint64("sequence") + .uint8("consistencyLevel") + .array("payload", { + type: "uint8", + readUntil: "eof", + }) + .string("end", { + greedy: true, + assert: (str) => str === "", + }); export function serialiseVAA(vaa: VAA) { - const body = [ - encode("uint8", vaa.version), - encode("uint32", vaa.guardianSetIndex), - encode("uint8", vaa.signatures.length), - ...(vaa.signatures.map((sig) => serialiseSignature(sig))), - vaaBody(vaa) - ] - return body.join("") + const body = [ + encode("uint8", vaa.version), + encode("uint32", vaa.guardianSetIndex), + encode("uint8", vaa.signatures.length), + ...vaa.signatures.map((sig) => serialiseSignature(sig)), + vaaBody(vaa), + ]; + return body.join(""); } export function vaaDigest(vaa: VAA) { - return solidityKeccak256(["bytes"], [solidityKeccak256(["bytes"], ["0x" + vaaBody(vaa)])]) + return solidityKeccak256( + ["bytes"], + [solidityKeccak256(["bytes"], ["0x" + vaaBody(vaa)])] + ); } function vaaBody(vaa: VAA) { - let payload_str: string - if (vaa.payload.type === "Other") { - payload_str = vaa.payload.hex - } else { - let payload = vaa.payload; - switch (payload.module) { - case "Core": - switch (payload.type) { - case "GuardianSetUpgrade": - payload_str = serialiseGuardianSetUpgrade(payload) - break - case "ContractUpgrade": - payload_str = serialiseCoreContractUpgrade(payload) - break - case "RecoverChainId": - payload_str = serialiseCoreContractRecoverChainId(payload) - break - default: - impossible(payload) - break - } - break - case "NFTBridge": - switch (payload.type) { - case "ContractUpgrade": - payload_str = serialisePortalContractUpgrade(payload) - break - case "RecoverChainId": - payload_str = serialisePortalContractRecoverChainId(payload) - break - case "RegisterChain": - payload_str = serialisePortalRegisterChain(payload) - break - case "Transfer": - payload_str = serialiseNFTBridgeTransfer(payload) - break - default: - impossible(payload) - break - } - break - case "TokenBridge": - switch (payload.type) { - case "ContractUpgrade": - payload_str = serialisePortalContractUpgrade(payload) - break - case "RecoverChainId": - payload_str = serialisePortalContractRecoverChainId(payload) - break - case "RegisterChain": - payload_str = serialisePortalRegisterChain(payload) - break - case "Transfer": - payload_str = serialiseTokenBridgeTransfer(payload) - break - case "TransferWithPayload": - payload_str = serialiseTokenBridgeTransferWithPayload(payload) - break - case "AttestMeta": - payload_str = serialiseTokenBridgeAttestMeta(payload) - break - default: - impossible(payload) - break - } - break - case "WormholeRelayer": - switch (payload.type) { - case "ContractUpgrade": - payload_str = serialisePortalContractUpgrade(payload) - break - case "RegisterChain": - payload_str = serialisePortalRegisterChain(payload) - break - case "SetDefaultDeliveryProvider": - payload_str = serialiseWormholeRelayerSetDefaultDeliveryProvider(payload) - break - default: - impossible(payload) - break - } - break - default: - impossible(payload) - break + let payload_str: string; + if (vaa.payload.type === "Other") { + payload_str = vaa.payload.hex; + } else { + let payload = vaa.payload; + switch (payload.module) { + case "Core": + switch (payload.type) { + case "GuardianSetUpgrade": + payload_str = serialiseGuardianSetUpgrade(payload); + break; + case "ContractUpgrade": + payload_str = serialiseCoreContractUpgrade(payload); + break; + case "RecoverChainId": + payload_str = serialiseCoreContractRecoverChainId(payload); + break; + default: + impossible(payload); + break; } + break; + case "NFTBridge": + switch (payload.type) { + case "ContractUpgrade": + payload_str = serialisePortalContractUpgrade(payload); + break; + case "RecoverChainId": + payload_str = serialisePortalContractRecoverChainId(payload); + break; + case "RegisterChain": + payload_str = serialisePortalRegisterChain(payload); + break; + case "Transfer": + payload_str = serialiseNFTBridgeTransfer(payload); + break; + default: + impossible(payload); + break; + } + break; + case "TokenBridge": + switch (payload.type) { + case "ContractUpgrade": + payload_str = serialisePortalContractUpgrade(payload); + break; + case "RecoverChainId": + payload_str = serialisePortalContractRecoverChainId(payload); + break; + case "RegisterChain": + payload_str = serialisePortalRegisterChain(payload); + break; + case "Transfer": + payload_str = serialiseTokenBridgeTransfer(payload); + break; + case "TransferWithPayload": + payload_str = serialiseTokenBridgeTransferWithPayload(payload); + break; + case "AttestMeta": + payload_str = serialiseTokenBridgeAttestMeta(payload); + break; + default: + impossible(payload); + break; + } + break; + case "WormholeRelayer": + switch (payload.type) { + case "ContractUpgrade": + payload_str = serialisePortalContractUpgrade(payload); + break; + case "RegisterChain": + payload_str = serialisePortalRegisterChain(payload); + break; + case "SetDefaultDeliveryProvider": + payload_str = + serialiseWormholeRelayerSetDefaultDeliveryProvider(payload); + break; + default: + impossible(payload); + break; + } + break; + default: + impossible(payload); + break; } - const body = [ - encode("uint32", vaa.timestamp), - encode("uint32", vaa.nonce), - encode("uint16", vaa.emitterChain), - encode("bytes32", hex(vaa.emitterAddress)), - encode("uint64", vaa.sequence), - encode("uint8", vaa.consistencyLevel), - payload_str - ] - return body.join("") + } + const body = [ + encode("uint32", vaa.timestamp), + encode("uint32", vaa.nonce), + encode("uint16", vaa.emitterChain), + encode("bytes32", hex(vaa.emitterAddress)), + encode("uint64", vaa.sequence), + encode("uint8", vaa.consistencyLevel), + payload_str, + ]; + return body.join(""); } export function sign(signers: string[], vaa: VAA): Signature[] { - const hash = vaaDigest(vaa) - const ec = new elliptic.ec("secp256k1") + const hash = vaaDigest(vaa); + const ec = new elliptic.ec("secp256k1"); - return signers.map((signer, i) => { - const key = ec.keyFromPrivate(signer) - const signature = key.sign(Buffer.from(hash.substr(2), "hex"), { canonical: true }) - const packed = [ - signature.r.toString("hex").padStart(64, "0"), - signature.s.toString("hex").padStart(64, "0"), - encode("uint8", signature.recoveryParam) - ].join("") - return { - guardianSetIndex: i, - signature: packed - } - }) + return signers.map((signer, i) => { + const key = ec.keyFromPrivate(signer); + const signature = key.sign(Buffer.from(hash.substr(2), "hex"), { + canonical: true, + }); + const packed = [ + signature.r.toString("hex").padStart(64, "0"), + signature.s.toString("hex").padStart(64, "0"), + encode("uint8", signature.recoveryParam), + ].join(""); + return { + guardianSetIndex: i, + signature: packed, + }; + }); } // Parse an address of given length, and render it as hex -const addressParser = (length: number) => new Parser() - .endianess("big") - .array("address", { - type: "uint8", - lengthInBytes: length, - formatter: (arr) => Buffer.from(arr).toString("hex") - }) +const addressParser = (length: number) => + new Parser().endianess("big").array("address", { + type: "uint8", + lengthInBytes: length, + formatter: (arr) => Buffer.from(arr).toString("hex"), + }); //////////////////////////////////////////////////////////////////////////////// // Guardian set upgrade export interface GuardianSetUpgrade { - module: "Core" - type: "GuardianSetUpgrade" - chain: number - newGuardianSetIndex: number - newGuardianSetLength: number - newGuardianSet: string[] + module: "Core"; + type: "GuardianSetUpgrade"; + chain: number; + newGuardianSetIndex: number; + newGuardianSetLength: number; + newGuardianSet: string[]; } // Parse a guardian set upgrade payload -const guardianSetUpgradeParser: P = new P(new Parser() +const guardianSetUpgradeParser: P = new P( + new Parser() .endianess("big") .string("module", { - length: 32, - encoding: "hex", - assert: Buffer.from("Core").toString("hex").padStart(64, "0"), - formatter: (_str) => "Core" + length: 32, + encoding: "hex", + assert: Buffer.from("Core").toString("hex").padStart(64, "0"), + formatter: (_str) => "Core", }) .uint8("type", { - assert: 2, - formatter: (_action) => "GuardianSetUpgrade" + assert: 2, + formatter: (_action) => "GuardianSetUpgrade", }) .uint16("chain") .uint32("newGuardianSetIndex") .uint8("newGuardianSetLength") .array("newGuardianSet", { - type: addressParser(20), - length: "newGuardianSetLength", - formatter: (arr: [{ address: string }]) => arr.map((addr) => addr.address) + type: addressParser(20), + length: "newGuardianSetLength", + formatter: (arr: [{ address: string }]) => + arr.map((addr) => addr.address), }) .string("end", { - greedy: true, - assert: str => str === "" - })) + greedy: true, + assert: (str) => str === "", + }) +); function serialiseGuardianSetUpgrade(payload: GuardianSetUpgrade): string { - const body = [ - encode("bytes32", encodeString(payload.module)), - encode("uint8", 2), - encode("uint16", payload.chain), - encode("uint32", payload.newGuardianSetIndex), - encode("uint8", payload.newGuardianSet.length), - ...payload.newGuardianSet - ] - return body.join("") + const body = [ + encode("bytes32", encodeString(payload.module)), + encode("uint8", 2), + encode("uint16", payload.chain), + encode("uint32", payload.newGuardianSetIndex), + encode("uint8", payload.newGuardianSet.length), + ...payload.newGuardianSet, + ]; + return body.join(""); } //////////////////////////////////////////////////////////////////////////////// // Contract upgrades export interface CoreContractUpgrade { - module: "Core" - type: "ContractUpgrade" - chain: number - address: string + module: "Core"; + type: "ContractUpgrade"; + chain: number; + address: string; } // Parse a core contract upgrade payload -const coreContractUpgradeParser: P = - new P(new Parser() - .endianess("big") - .string("module", { - length: 32, - encoding: "hex", - assert: Buffer.from("Core").toString("hex").padStart(64, "0"), - formatter: (_str) => "Core" - }) - .uint8("type", { - assert: 1, - formatter: (_action) => "ContractUpgrade" - }) - .uint16("chain") - .array("address", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .string("end", { - greedy: true, - assert: str => str === "" - })) +const coreContractUpgradeParser: P = new P( + new Parser() + .endianess("big") + .string("module", { + length: 32, + encoding: "hex", + assert: Buffer.from("Core").toString("hex").padStart(64, "0"), + formatter: (_str) => "Core", + }) + .uint8("type", { + assert: 1, + formatter: (_action) => "ContractUpgrade", + }) + .uint16("chain") + .array("address", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .string("end", { + greedy: true, + assert: (str) => str === "", + }) +); function serialiseCoreContractUpgrade(payload: CoreContractUpgrade): string { - const body = [ - encode("bytes32", encodeString(payload.module)), - encode("uint8", 1), - encode("uint16", payload.chain), - encode("bytes32", payload.address) - ] - return body.join("") + const body = [ + encode("bytes32", encodeString(payload.module)), + encode("uint8", 1), + encode("uint16", payload.chain), + encode("bytes32", payload.address), + ]; + return body.join(""); } -export interface PortalContractUpgrade { - module: Module - type: "ContractUpgrade" - chain: number - address: string +export interface PortalContractUpgrade< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +> { + module: Module; + type: "ContractUpgrade"; + chain: number; + address: string; } // Parse a portal contract upgrade payload -function portalContractUpgradeParser(module: Module): P> { - return new P(new Parser() - .endianess("big") - .string("module", { - length: 32, - encoding: "hex", - assert: Buffer.from(module).toString("hex").padStart(64, "0"), - formatter: (_str: string) => module - }) - .uint8("type", { - assert: 2, - formatter: (_action: number) => "ContractUpgrade" - }) - .uint16("chain") - .array("address", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .string("end", { - greedy: true, - assert: str => str === "" - })) +function portalContractUpgradeParser< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +>(module: Module): P> { + return new P( + new Parser() + .endianess("big") + .string("module", { + length: 32, + encoding: "hex", + assert: Buffer.from(module).toString("hex").padStart(64, "0"), + formatter: (_str: string) => module, + }) + .uint8("type", { + assert: 2, + formatter: (_action: number) => "ContractUpgrade", + }) + .uint16("chain") + .array("address", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .string("end", { + greedy: true, + assert: (str) => str === "", + }) + ); } -function serialisePortalContractUpgrade(payload: PortalContractUpgrade): string { - const body = [ - encode("bytes32", encodeString(payload.module)), - encode("uint8", 2), - encode("uint16", payload.chain), - encode("bytes32", payload.address) - ] - return body.join("") +function serialisePortalContractUpgrade< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +>(payload: PortalContractUpgrade): string { + const body = [ + encode("bytes32", encodeString(payload.module)), + encode("uint8", 2), + encode("uint16", payload.chain), + encode("bytes32", payload.address), + ]; + return body.join(""); } //////////////////////////////////////////////////////////////////////////////// // Registrations -export interface PortalRegisterChain { - module: Module - type: "RegisterChain" - chain: number - emitterChain: number - emitterAddress: string +export interface PortalRegisterChain< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +> { + module: Module; + type: "RegisterChain"; + chain: number; + emitterChain: number; + emitterAddress: string; } // Parse a portal chain registration payload -function portalRegisterChainParser(module: Module): P> { - return new P(new Parser() - .endianess("big") - .string("module", { - length: 32, - encoding: "hex", - assert: Buffer.from(module).toString("hex").padStart(64, "0"), - formatter: (_str) => module - }) - .uint8("type", { - assert: 1, - formatter: (_action) => "RegisterChain" - }) - .uint16("chain") - .uint16("emitterChain") - .array("emitterAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .string("end", { - greedy: true, - assert: str => str === "" - }) - ) +function portalRegisterChainParser< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +>(module: Module): P> { + return new P( + new Parser() + .endianess("big") + .string("module", { + length: 32, + encoding: "hex", + assert: Buffer.from(module).toString("hex").padStart(64, "0"), + formatter: (_str) => module, + }) + .uint8("type", { + assert: 1, + formatter: (_action) => "RegisterChain", + }) + .uint16("chain") + .uint16("emitterChain") + .array("emitterAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .string("end", { + greedy: true, + assert: (str) => str === "", + }) + ); } -function serialisePortalRegisterChain(payload: PortalRegisterChain): string { - const body = [ - encode("bytes32", encodeString(payload.module)), - encode("uint8", 1), - encode("uint16", payload.chain), - encode("uint16", payload.emitterChain), - encode("bytes32", payload.emitterAddress) - ] - return body.join("") +function serialisePortalRegisterChain< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +>(payload: PortalRegisterChain): string { + const body = [ + encode("bytes32", encodeString(payload.module)), + encode("uint8", 1), + encode("uint16", payload.chain), + encode("uint16", payload.emitterChain), + encode("bytes32", payload.emitterAddress), + ]; + return body.join(""); } //////////////////////////////////////////////////////////////////////////////// // RecoverChainId export interface CoreContractRecoverChainId { - module: "Core" - type: "RecoverChainId" - evmChainId: bigint - newChainId: number + module: "Core"; + type: "RecoverChainId"; + evmChainId: bigint; + newChainId: number; } // Parse a core contract recoverChainId payload function coreContractRecoverChainId(): P { - return new P(new Parser() - .endianess("big") - .string("module", { - length: 32, - encoding: "hex", - assert: Buffer.from("Core").toString("hex").padStart(64, "0"), - formatter: (_str) => "Core" - }) - .uint8("type", { - assert: 5, - formatter: (_action) => "RecoverChainId" - }) - .array("evmChainId", { - type: "uint8", - lengthInBytes: 32, - formatter: (bytes) => BigNumber.from(bytes).toBigInt() - }) - .uint16("newChainId") - .string("end", { - greedy: true, - assert: str => str === "" - })) + return new P( + new Parser() + .endianess("big") + .string("module", { + length: 32, + encoding: "hex", + assert: Buffer.from("Core").toString("hex").padStart(64, "0"), + formatter: (_str) => "Core", + }) + .uint8("type", { + assert: 5, + formatter: (_action) => "RecoverChainId", + }) + .array("evmChainId", { + type: "uint8", + lengthInBytes: 32, + formatter: (bytes) => BigNumber.from(bytes).toBigInt(), + }) + .uint16("newChainId") + .string("end", { + greedy: true, + assert: (str) => str === "", + }) + ); } -function serialiseCoreContractRecoverChainId(payload: CoreContractRecoverChainId): string { - const body = [ - encode("bytes32", encodeString(payload.module)), - encode("uint8", 5), - encode("uint256", payload.evmChainId), - encode("uint16", payload.newChainId) - ] - return body.join("") +function serialiseCoreContractRecoverChainId( + payload: CoreContractRecoverChainId +): string { + const body = [ + encode("bytes32", encodeString(payload.module)), + encode("uint8", 5), + encode("uint256", payload.evmChainId), + encode("uint16", payload.newChainId), + ]; + return body.join(""); } -export interface PortalContractRecoverChainId { - module: Module - type: "RecoverChainId" - evmChainId: bigint - newChainId: number +export interface PortalContractRecoverChainId< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +> { + module: Module; + type: "RecoverChainId"; + evmChainId: bigint; + newChainId: number; } // Parse a portal contract recoverChainId payload -function portalContractRecoverChainId(module: Module): P> { - return new P(new Parser() - .endianess("big") - .string("module", { - length: 32, - encoding: "hex", - assert: Buffer.from(module).toString("hex").padStart(64, "0"), - formatter: (_str: string) => module - }) - .uint8("type", { - assert: 3, - formatter: (_action: number) => "RecoverChainId" - }) - .array("evmChainId", { - type: "uint8", - lengthInBytes: 32, - formatter: (bytes) => BigNumber.from(bytes).toBigInt() - }) - .uint16("newChainId") - .string("end", { - greedy: true, - assert: str => str === "" - })) +function portalContractRecoverChainId< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +>(module: Module): P> { + return new P( + new Parser() + .endianess("big") + .string("module", { + length: 32, + encoding: "hex", + assert: Buffer.from(module).toString("hex").padStart(64, "0"), + formatter: (_str: string) => module, + }) + .uint8("type", { + assert: 3, + formatter: (_action: number) => "RecoverChainId", + }) + .array("evmChainId", { + type: "uint8", + lengthInBytes: 32, + formatter: (bytes) => BigNumber.from(bytes).toBigInt(), + }) + .uint16("newChainId") + .string("end", { + greedy: true, + assert: (str) => str === "", + }) + ); } -function serialisePortalContractRecoverChainId(payload: PortalContractRecoverChainId): string { - const body = [ - encode("bytes32", encodeString(payload.module)), - encode("uint8", 3), - encode("uint256", payload.evmChainId), - encode("uint16", payload.newChainId) - ] - return body.join("") +function serialisePortalContractRecoverChainId< + Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer", +>(payload: PortalContractRecoverChainId): string { + const body = [ + encode("bytes32", encodeString(payload.module)), + encode("uint8", 3), + encode("uint256", payload.evmChainId), + encode("uint16", payload.newChainId), + ]; + return body.join(""); } //////////////////////////////////////////////////////////////////////////////// @@ -605,329 +644,358 @@ function serialisePortalContractRecoverChainId { - return new P(new Parser() - .endianess("big") - .string("module", { - length: (_) => 0, - formatter: (_) => "TokenBridge" - }) - .uint8("type", { - assert: 1, - formatter: (_action) => "Transfer" - }) - .array("amount", { - type: "uint8", - lengthInBytes: 32, - formatter: (bytes) => BigNumber.from(bytes).toBigInt() - }) - .array("tokenAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .uint16("tokenChain") - .array("toAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .uint16("chain") - .array("fee", { - type: "uint8", - lengthInBytes: 32, - formatter: (bytes) => BigNumber.from(bytes).toBigInt() - }) - .string("end", { - greedy: true, - assert: str => str === "" - }) - ) + return new P( + new Parser() + .endianess("big") + .string("module", { + length: (_) => 0, + formatter: (_) => "TokenBridge", + }) + .uint8("type", { + assert: 1, + formatter: (_action) => "Transfer", + }) + .array("amount", { + type: "uint8", + lengthInBytes: 32, + formatter: (bytes) => BigNumber.from(bytes).toBigInt(), + }) + .array("tokenAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .uint16("tokenChain") + .array("toAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .uint16("chain") + .array("fee", { + type: "uint8", + lengthInBytes: 32, + formatter: (bytes) => BigNumber.from(bytes).toBigInt(), + }) + .string("end", { + greedy: true, + assert: (str) => str === "", + }) + ); } function serialiseTokenBridgeTransfer(payload: TokenBridgeTransfer): string { - const body = [ - encode("uint8", 1), - encode("uint256", payload.amount), - encode("bytes32", hex(payload.tokenAddress)), - encode("uint16", payload.tokenChain), - encode("bytes32", hex(payload.toAddress)), - encode("uint16", payload.chain), - encode("uint256", payload.fee), - ] - return body.join("") + const body = [ + encode("uint8", 1), + encode("uint256", payload.amount), + encode("bytes32", hex(payload.tokenAddress)), + encode("uint16", payload.tokenChain), + encode("bytes32", hex(payload.toAddress)), + encode("uint16", payload.chain), + encode("uint256", payload.fee), + ]; + return body.join(""); } // payload 2 export interface TokenBridgeAttestMeta { - module: "TokenBridge" - type: "AttestMeta" - chain: 0, - tokenAddress: string - tokenChain: number - decimals: number - symbol: string - name: string + module: "TokenBridge"; + type: "AttestMeta"; + chain: 0; + tokenAddress: string; + tokenChain: number; + decimals: number; + symbol: string; + name: string; } function tokenBridgeAttestMetaParser(): P { - return new P(new Parser() - .endianess("big") - .string("module", { - length: (_) => 0, - formatter: (_) => "TokenBridge" - }) - .string("chain", { - length: (_) => 0, - formatter: (_) => 0 - }) - .uint8("type", { - assert: 2, - formatter: (_action) => "AttestMeta" - }) - .array("tokenAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .uint16("tokenChain") - .uint8("decimals") - .array("symbol", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr: Uint8Array) => Buffer.from(arr).toString("utf8", arr.findIndex((val) => val != 0)) - }) - .array("name", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr: Uint8Array) => Buffer.from(arr).toString("utf8", arr.findIndex((val) => val != 0)) - }) - .string("end", { - greedy: true, - assert: str => str === "" - }) - ) + return new P( + new Parser() + .endianess("big") + .string("module", { + length: (_) => 0, + formatter: (_) => "TokenBridge", + }) + .string("chain", { + length: (_) => 0, + formatter: (_) => 0, + }) + .uint8("type", { + assert: 2, + formatter: (_action) => "AttestMeta", + }) + .array("tokenAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .uint16("tokenChain") + .uint8("decimals") + .array("symbol", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr: Uint8Array) => + Buffer.from(arr).toString( + "utf8", + arr.findIndex((val) => val != 0) + ), + }) + .array("name", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr: Uint8Array) => + Buffer.from(arr).toString( + "utf8", + arr.findIndex((val) => val != 0) + ), + }) + .string("end", { + greedy: true, + assert: (str) => str === "", + }) + ); } -function serialiseTokenBridgeAttestMeta(payload: TokenBridgeAttestMeta): string { - const body = [ - encode("uint8", 2), - encode("bytes32", hex(payload.tokenAddress)), - encode("uint16", payload.tokenChain), - encode("uint8", payload.decimals), - encode("bytes32", encodeStringRight(payload.symbol)), - encode("bytes32", encodeStringRight(payload.name)), - ] - return body.join("") +function serialiseTokenBridgeAttestMeta( + payload: TokenBridgeAttestMeta +): string { + const body = [ + encode("uint8", 2), + encode("bytes32", hex(payload.tokenAddress)), + encode("uint16", payload.tokenChain), + encode("uint8", payload.decimals), + encode("bytes32", encodeStringRight(payload.symbol)), + encode("bytes32", encodeStringRight(payload.name)), + ]; + return body.join(""); } // payload 3 export interface TokenBridgeTransferWithPayload { - module: "TokenBridge" - type: "TransferWithPayload" - amount: bigint - tokenAddress: string - tokenChain: number - toAddress: string - chain: number - fromAddress: string, - payload: string + module: "TokenBridge"; + type: "TransferWithPayload"; + amount: bigint; + tokenAddress: string; + tokenChain: number; + toAddress: string; + chain: number; + fromAddress: string; + payload: string; } function tokenBridgeTransferWithPayloadParser(): P { - return new P(new Parser() - .endianess("big") - .string("module", { - length: (_) => 0, - formatter: (_) => "TokenBridge" - }) - .uint8("type", { - assert: 3, - formatter: (_action) => "TransferWithPayload" - }) - .array("amount", { - type: "uint8", - lengthInBytes: 32, - formatter: (bytes) => BigNumber.from(bytes).toBigInt() - }) - .array("tokenAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .uint16("tokenChain") - .array("toAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .uint16("chain") - .array("fromAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }). - array("payload", { - type: "uint8", - greedy: true, - readUntil: "eof", - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - ) + return new P( + new Parser() + .endianess("big") + .string("module", { + length: (_) => 0, + formatter: (_) => "TokenBridge", + }) + .uint8("type", { + assert: 3, + formatter: (_action) => "TransferWithPayload", + }) + .array("amount", { + type: "uint8", + lengthInBytes: 32, + formatter: (bytes) => BigNumber.from(bytes).toBigInt(), + }) + .array("tokenAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .uint16("tokenChain") + .array("toAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .uint16("chain") + .array("fromAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .array("payload", { + type: "uint8", + greedy: true, + readUntil: "eof", + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + ); } -function serialiseTokenBridgeTransferWithPayload(payload: TokenBridgeTransferWithPayload): string { - const body = [ - encode("uint8", 3), - encode("uint256", payload.amount), - encode("bytes32", hex(payload.tokenAddress)), - encode("uint16", payload.tokenChain), - encode("bytes32", hex(payload.toAddress)), - encode("uint16", payload.chain), - encode("bytes32", hex(payload.fromAddress)), - payload.payload.substring(2) - ] - return body.join("") +function serialiseTokenBridgeTransferWithPayload( + payload: TokenBridgeTransferWithPayload +): string { + const body = [ + encode("uint8", 3), + encode("uint256", payload.amount), + encode("bytes32", hex(payload.tokenAddress)), + encode("uint16", payload.tokenChain), + encode("bytes32", hex(payload.toAddress)), + encode("uint16", payload.chain), + encode("bytes32", hex(payload.fromAddress)), + payload.payload.substring(2), + ]; + return body.join(""); } //////////////////////////////////////////////////////////////////////////////// // NFT bridge export interface NFTBridgeTransfer { - module: "NFTBridge" - type: "Transfer" - tokenAddress: string - tokenChain: number - tokenSymbol: string - tokenName: string - tokenId: bigint - tokenURI: string - toAddress: string - chain: number + module: "NFTBridge"; + type: "Transfer"; + tokenAddress: string; + tokenChain: number; + tokenSymbol: string; + tokenName: string; + tokenId: bigint; + tokenURI: string; + toAddress: string; + chain: number; } function nftBridgeTransferParser(): P { - return new P(new Parser() - .endianess("big") - .string("module", { - length: (_) => 0, - formatter: (_) => "NFTBridge" - }) - .uint8("type", { - assert: 1, - formatter: (_action) => "Transfer" - }) - .array("tokenAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .uint16("tokenChain") - .array("tokenSymbol", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr: Uint8Array) => Buffer.from(arr).toString("utf8", arr.findIndex((val) => val != 0)) - }) - .array("tokenName", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr: Uint8Array) => Buffer.from(arr).toString("utf8", arr.findIndex((val) => val != 0)) - }) - .array("tokenId", { - type: "uint8", - lengthInBytes: 32, - formatter: (bytes) => BigNumber.from(bytes).toBigInt() - }) - .uint8("tokenURILength") - .array("tokenURI", { - type: "uint8", - lengthInBytes: function() { - return (this as any).tokenURILength - }, - formatter: (arr: Uint8Array) => Buffer.from(arr).toString("utf8") - }) - .array("toAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .uint16("chain") - .string("end", { - greedy: true, - assert: str => str === "" - }) - ) + return new P( + new Parser() + .endianess("big") + .string("module", { + length: (_) => 0, + formatter: (_) => "NFTBridge", + }) + .uint8("type", { + assert: 1, + formatter: (_action) => "Transfer", + }) + .array("tokenAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .uint16("tokenChain") + .array("tokenSymbol", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr: Uint8Array) => + Buffer.from(arr).toString( + "utf8", + arr.findIndex((val) => val != 0) + ), + }) + .array("tokenName", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr: Uint8Array) => + Buffer.from(arr).toString( + "utf8", + arr.findIndex((val) => val != 0) + ), + }) + .array("tokenId", { + type: "uint8", + lengthInBytes: 32, + formatter: (bytes) => BigNumber.from(bytes).toBigInt(), + }) + .uint8("tokenURILength") + .array("tokenURI", { + type: "uint8", + lengthInBytes: function () { + return (this as any).tokenURILength; + }, + formatter: (arr: Uint8Array) => Buffer.from(arr).toString("utf8"), + }) + .array("toAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .uint16("chain") + .string("end", { + greedy: true, + assert: (str) => str === "", + }) + ); } function serialiseNFTBridgeTransfer(payload: NFTBridgeTransfer): string { - const body = [ - encode("uint8", 1), - encode("bytes32", hex(payload.tokenAddress)), - encode("uint16", payload.tokenChain), - encode("bytes32", encodeStringRight(payload.tokenSymbol)), - encode("bytes32", encodeStringRight(payload.tokenName)), - encode("uint256", payload.tokenId), - encode("uint8", payload.tokenURI.length), - Buffer.from(payload.tokenURI, "utf8").toString("hex"), - encode("bytes32", hex(payload.toAddress)), - encode("uint16", payload.chain), - ] - return body.join("") + const body = [ + encode("uint8", 1), + encode("bytes32", hex(payload.tokenAddress)), + encode("uint16", payload.tokenChain), + encode("bytes32", encodeStringRight(payload.tokenSymbol)), + encode("bytes32", encodeStringRight(payload.tokenName)), + encode("uint256", payload.tokenId), + encode("uint8", payload.tokenURI.length), + Buffer.from(payload.tokenURI, "utf8").toString("hex"), + encode("bytes32", hex(payload.toAddress)), + encode("uint16", payload.chain), + ]; + return body.join(""); } //////////////////////////////////////////////////////////////////////////////// // WormholeRelayer export interface WormholeRelayerSetDefaultDeliveryProvider { - module: "WormholeRelayer" - type: "SetDefaultDeliveryProvider" - relayProviderAddress: string - chain: number + module: "WormholeRelayer"; + type: "SetDefaultDeliveryProvider"; + relayProviderAddress: string; + chain: number; } function wormholeRelayerSetDefaultDeliveryProvider(): P { - return new P(new Parser() - .endianess("big") - .string("module", { - length: 32, - encoding: "hex", - assert: Buffer.from("WormholeRelayer").toString("hex").padStart(64, "0"), - formatter: (_str: string) => "WormholeRelayer" - }) - .uint8("type", { - assert: 3, - formatter: (_action) => "SetDefaultDeliveryProvider" - }) - .uint16("chain") - .array("relayProviderAddress", { - type: "uint8", - lengthInBytes: 32, - formatter: (arr) => "0x" + Buffer.from(arr).toString("hex") - }) - .string("end", { - greedy: true, - assert: str => str === "" - }) - ) + return new P( + new Parser() + .endianess("big") + .string("module", { + length: 32, + encoding: "hex", + assert: Buffer.from("WormholeRelayer") + .toString("hex") + .padStart(64, "0"), + formatter: (_str: string) => "WormholeRelayer", + }) + .uint8("type", { + assert: 3, + formatter: (_action) => "SetDefaultDeliveryProvider", + }) + .uint16("chain") + .array("relayProviderAddress", { + type: "uint8", + lengthInBytes: 32, + formatter: (arr) => "0x" + Buffer.from(arr).toString("hex"), + }) + .string("end", { + greedy: true, + assert: (str) => str === "", + }) + ); } -function serialiseWormholeRelayerSetDefaultDeliveryProvider(payload: WormholeRelayerSetDefaultDeliveryProvider): string { - const body = [ - encode("bytes32", encodeString(payload.module)), - encode("uint8", 3), - encode("uint16", payload.chain), - encode("bytes32", hex(payload.relayProviderAddress)), - ] - return body.join("") +function serialiseWormholeRelayerSetDefaultDeliveryProvider( + payload: WormholeRelayerSetDefaultDeliveryProvider +): string { + const body = [ + encode("bytes32", encodeString(payload.module)), + encode("uint8", 3), + encode("uint16", payload.chain), + encode("bytes32", hex(payload.relayProviderAddress)), + ]; + return body.join(""); } // This function should be called after pattern matching on all possible options @@ -937,58 +1005,71 @@ function serialiseWormholeRelayerSetDefaultDeliveryProvider(payload: WormholeRel // the call to this function will then fail to compile, drawing attention to an // unhandled case somewhere. export function impossible(a: never): never { - throw new Error(`Impossible: ${a}`) + throw new Error(`Impossible: ${a}`); } //////////////////////////////////////////////////////////////////////////////// // Encoder utils -export type Encoding - = "uint8" - | "uint16" - | "uint32" - | "uint64" - | "uint128" - | "uint256" - | "bytes32" - | "address" +export type Encoding = + | "uint8" + | "uint16" + | "uint32" + | "uint64" + | "uint128" + | "uint256" + | "bytes32" + | "address"; export function typeWidth(type: Encoding): number { - switch (type) { - case "uint8": return 1 - case "uint16": return 2 - case "uint32": return 4 - case "uint64": return 8 - case "uint128": return 16 - case "uint256": return 32 - case "bytes32": return 32 - case "address": return 20 - } + switch (type) { + case "uint8": + return 1; + case "uint16": + return 2; + case "uint32": + return 4; + case "uint64": + return 8; + case "uint128": + return 16; + case "uint256": + return 32; + case "bytes32": + return 32; + case "address": + return 20; + } } // Couldn't find a satisfactory binary serialisation solution, so we just use // the ethers library's encoding logic export function encode(type: Encoding, val: any): string { - // ethers operates on hex strings (sigh) and left pads everything to 32 - // bytes (64 characters). We take last 2*n characters where n is the width - // of the type being serialised in bytes (since a byte is represented as 2 - // digits in hex). - return ethers.utils.defaultAbiCoder.encode([type], [val]).substr(-2 * typeWidth(type)) + // ethers operates on hex strings (sigh) and left pads everything to 32 + // bytes (64 characters). We take last 2*n characters where n is the width + // of the type being serialised in bytes (since a byte is represented as 2 + // digits in hex). + return ethers.utils.defaultAbiCoder + .encode([type], [val]) + .substr(-2 * typeWidth(type)); } // Encode a string as binary left-padded to 32 bytes, represented as a hex // string (64 chars long) export function encodeString(str: string): Buffer { - return Buffer.from(Buffer.from(str).toString("hex").padStart(64, "0"), "hex") + return Buffer.from(Buffer.from(str).toString("hex").padStart(64, "0"), "hex"); } // Encode a string as binary right-padded to 32 bytes, represented as a hex // string (64 chars long) export function encodeStringRight(str: string): Buffer { - return Buffer.from(Buffer.from(str).toString("hex").padEnd(64, "0"), "hex") + return Buffer.from(Buffer.from(str).toString("hex").padEnd(64, "0"), "hex"); } // Turn hex string with potentially missing 0x prefix into Buffer function hex(x: string): Buffer { - return Buffer.from(ethers.utils.hexlify(x, { allowMissingPrefix: true }).substring(2), "hex") + return Buffer.from( + ethers.utils.hexlify(x, { allowMissingPrefix: true }).substring(2), + "hex" + ); } diff --git a/clients/js/src/xpla.ts b/clients/js/src/xpla.ts index 79afea397..f5c404c3f 100644 --- a/clients/js/src/xpla.ts +++ b/clients/js/src/xpla.ts @@ -139,7 +139,7 @@ export async function execute_xpla( break; } case "WormholeRelayer": - throw Error("Wormhole Relayer not supported on Xpla"); + throw Error("Wormhole Relayer not supported on Xpla"); default: target_contract = impossible(payload); execute_msg = impossible(payload); diff --git a/sdk/js/src/aptos/api/coreBridge.ts b/sdk/js/src/aptos/api/coreBridge.ts index c7d6cf0fc..9be192144 100644 --- a/sdk/js/src/aptos/api/coreBridge.ts +++ b/sdk/js/src/aptos/api/coreBridge.ts @@ -5,7 +5,7 @@ import { ChainId } from "../../utils"; export const upgradeGuardianSet = ( coreBridgeAddress: string, - vaa: Uint8Array, + vaa: Uint8Array ): Types.EntryFunctionPayload => { if (!coreBridgeAddress) throw new Error("Need core bridge address."); return { @@ -22,12 +22,17 @@ export const initWormhole = ( chainId: ChainId, governanceChainId: number, governanceContract: Uint8Array, - initialGuardian: Uint8Array, + initialGuardian: Uint8Array ): Types.EntryFunctionPayload => { if (!coreBridgeAddress) throw new Error("Need core bridge address."); return { function: `${coreBridgeAddress}::wormhole::init`, type_arguments: [], - arguments: [chainId, governanceChainId, governanceContract, initialGuardian], + arguments: [ + chainId, + governanceChainId, + governanceContract, + initialGuardian, + ], }; }; diff --git a/sdk/js/src/aptos/api/tokenBridge.ts b/sdk/js/src/aptos/api/tokenBridge.ts index fa3c5ab8e..255eacd97 100644 --- a/sdk/js/src/aptos/api/tokenBridge.ts +++ b/sdk/js/src/aptos/api/tokenBridge.ts @@ -17,16 +17,16 @@ import { export const attestToken = ( tokenBridgeAddress: string, tokenChain: ChainId | ChainName, - tokenAddress: string, + tokenAddress: string ): Types.EntryFunctionPayload => { if (!tokenBridgeAddress) throw new Error("Need token bridge address."); const assetType = getAssetFullyQualifiedType( tokenBridgeAddress, coalesceChainId(tokenChain), - tokenAddress, + tokenAddress ); if (!assetType) throw new Error("Invalid asset address."); - + return { function: `${tokenBridgeAddress}::attest_token::attest_token_entry`, type_arguments: [assetType], @@ -40,7 +40,7 @@ export const completeTransfer = async ( client: AptosClient, tokenBridgeAddress: string, transferVAA: Uint8Array, - feeRecipient: string, + feeRecipient: string ): Promise => { if (!tokenBridgeAddress) throw new Error("Need token bridge address."); @@ -52,7 +52,7 @@ export const completeTransfer = async ( if (parsedVAA.ToChain !== CHAIN_ID_APTOS) { throw new Error("Transfer is not destined for Aptos"); } - + assertChain(parsedVAA.FromChain); const assetType = parsedVAA.FromChain === CHAIN_ID_APTOS @@ -78,7 +78,7 @@ export const completeTransfer = async ( export const completeTransferAndRegister = async ( client: AptosClient, tokenBridgeAddress: string, - transferVAA: Uint8Array, + transferVAA: Uint8Array ): Promise => { if (!tokenBridgeAddress) throw new Error("Need token bridge address."); @@ -90,7 +90,7 @@ export const completeTransferAndRegister = async ( if (parsedVAA.ToChain !== CHAIN_ID_APTOS) { throw new Error("Transfer is not destined for Aptos"); } - + assertChain(parsedVAA.FromChain); const assetType = parsedVAA.FromChain === CHAIN_ID_APTOS @@ -117,21 +117,23 @@ export const completeTransferWithPayload = ( _tokenBridgeAddress: string, _tokenChain: ChainId | ChainName, _tokenAddress: string, - _vaa: Uint8Array, + _vaa: Uint8Array ): Types.EntryFunctionPayload => { - throw new Error("Completing transfers with payload is not yet supported in the sdk"); + throw new Error( + "Completing transfers with payload is not yet supported in the sdk" + ); }; /** - * Construct a payload for a transaction that registers a coin defined by the given origin chain + * Construct a payload for a transaction that registers a coin defined by the given origin chain * ID and address to the sender's account. - * + * * The bytecode was compiled from the following Move code: * ```move * script { * use aptos_framework::coin; * use aptos_framework::signer; - * + * * fun main(user: &signer) { * if (!coin::is_account_registered(signer::address_of(user))) { * coin::register(user); @@ -170,7 +172,9 @@ export const registerCoin = ( // Deploy coin // don't need `signer` and `&signer` in argument list because the Move VM will inject them -export const deployCoin = (tokenBridgeAddress: string): Types.EntryFunctionPayload => { +export const deployCoin = ( + tokenBridgeAddress: string +): Types.EntryFunctionPayload => { if (!tokenBridgeAddress) throw new Error("Need token bridge address."); return { function: `${tokenBridgeAddress}::deploy_coin::deploy_coin`, @@ -183,7 +187,7 @@ export const deployCoin = (tokenBridgeAddress: string): Types.EntryFunctionPaylo export const registerChain = ( tokenBridgeAddress: string, - vaa: Uint8Array, + vaa: Uint8Array ): Types.EntryFunctionPayload => { if (!tokenBridgeAddress) throw new Error("Need token bridge address."); return { diff --git a/sdk/js/src/bridge/parseSequenceFromLog.ts b/sdk/js/src/bridge/parseSequenceFromLog.ts index c44a82962..d503b0f8a 100644 --- a/sdk/js/src/bridge/parseSequenceFromLog.ts +++ b/sdk/js/src/bridge/parseSequenceFromLog.ts @@ -1,4 +1,7 @@ -import { TransactionResponse, VersionedTransactionResponse } from "@solana/web3.js"; +import { + TransactionResponse, + VersionedTransactionResponse, +} from "@solana/web3.js"; import { TxInfo } from "@terra-money/terra.js"; import { TxInfo as XplaTxInfo } from "@xpla/xpla.js"; import { AptosClient, Types } from "aptos"; @@ -105,7 +108,9 @@ export function parseSequenceFromLogInjective(info: any): string { } const SOLANA_SEQ_LOG = "Program log: Sequence: "; -export function parseSequenceFromLogSolana(info: TransactionResponse | VersionedTransactionResponse) { +export function parseSequenceFromLogSolana( + info: TransactionResponse | VersionedTransactionResponse +) { // TODO: better parsing, safer const sequence = info.meta?.logMessages ?.filter((msg) => msg.startsWith(SOLANA_SEQ_LOG))?.[0] diff --git a/sdk/js/src/index.ts b/sdk/js/src/index.ts index ce777a7cb..5a88dc4a5 100644 --- a/sdk/js/src/index.ts +++ b/sdk/js/src/index.ts @@ -16,6 +16,6 @@ export * as token_bridge from "./token_bridge"; export * as nft_bridge from "./nft_bridge"; export * as algorand from "./algorand"; export * as sui from "./sui"; -export * as relayer from "./relayer" +export * as relayer from "./relayer"; export { postVaaSolana, postVaaSolanaWithRetry } from "./solana"; diff --git a/sdk/js/src/mock/governance.ts b/sdk/js/src/mock/governance.ts index d20c2f903..a79e1c37c 100644 --- a/sdk/js/src/mock/governance.ts +++ b/sdk/js/src/mock/governance.ts @@ -265,6 +265,4 @@ export class GovernanceEmitter extends MockEmitter { uptickSequence ); } - - } diff --git a/sdk/js/src/relayer/__tests__/relay_provider.ts b/sdk/js/src/relayer/__tests__/relay_provider.ts index 5ac5ae6eb..31672acdf 100644 --- a/sdk/js/src/relayer/__tests__/relay_provider.ts +++ b/sdk/js/src/relayer/__tests__/relay_provider.ts @@ -1,45 +1,52 @@ -import { afterAll, beforeEach, describe, expect, jest, test} from "@jest/globals"; +import { + afterAll, + beforeEach, + describe, + expect, + jest, + test, +} from "@jest/globals"; import { ethers } from "ethers"; -import { DeliveryProvider__factory } from "../../ethers-contracts" -import {getAddressInfo} from "../consts" -import {getDefaultProvider} from "../relayer/helpers" -import {CHAINS, ChainId, ChainName, Network} from "../../../" -import {getNetwork, PRIVATE_KEY, isCI} from "./utils/utils"; - +import { DeliveryProvider__factory } from "../../ethers-contracts"; +import { getAddressInfo } from "../consts"; +import { getDefaultProvider } from "../relayer/helpers"; +import { CHAINS, ChainId, ChainName, Network } from "../../../"; +import { getNetwork, PRIVATE_KEY, isCI } from "./utils/utils"; const network: Network = getNetwork(); const ci: boolean = isCI(); -const sourceChain = network == 'DEVNET' ? "ethereum" : "avalanche"; -const targetChain = network == 'DEVNET' ? "bsc" : "celo"; +const sourceChain = network == "DEVNET" ? "ethereum" : "avalanche"; +const targetChain = network == "DEVNET" ? "bsc" : "celo"; const sourceChainId = CHAINS[sourceChain]; const targetChainId = CHAINS[targetChain]; describe("Relay Provider Test", () => { - - const addressInfo = getAddressInfo(sourceChain, network); const provider = getDefaultProvider(network, sourceChain, ci); // signers const oracleDeployer = new ethers.Wallet(PRIVATE_KEY, provider); const deliveryProviderAddress = addressInfo.mockDeliveryProviderAddress; - if(!deliveryProviderAddress) throw Error("No relay provider address"); - const deliveryProvider = DeliveryProvider__factory.connect(deliveryProviderAddress, oracleDeployer); - + if (!deliveryProviderAddress) throw Error("No relay provider address"); + const deliveryProvider = DeliveryProvider__factory.connect( + deliveryProviderAddress, + oracleDeployer + ); describe("Read Prices Correctly", () => { test("readPrices", async () => { const tokenPrice = ethers.BigNumber.from("100000"); const gasPrice = ethers.utils.parseUnits("300", "gwei"); - - const tokenPriceReturned = await deliveryProvider.nativeCurrencyPrice(targetChainId); + + const tokenPriceReturned = await deliveryProvider.nativeCurrencyPrice( + targetChainId + ); const gasPriceReturned = await deliveryProvider.gasPrice(targetChainId); expect(tokenPriceReturned.toString()).toBe(tokenPrice.toString()); expect(gasPriceReturned.toString()).toBe(gasPrice.toString()); - }); }); }); diff --git a/sdk/js/src/relayer/__tests__/utils/utils.ts b/sdk/js/src/relayer/__tests__/utils/utils.ts index 49ec50296..53f6b0ef9 100644 --- a/sdk/js/src/relayer/__tests__/utils/utils.ts +++ b/sdk/js/src/relayer/__tests__/utils/utils.ts @@ -1,26 +1,32 @@ import { Network } from "../../../utils"; import { PublicKey } from "@solana/web3.js"; import { ethers } from "ethers"; -import {ETH_PRIVATE_KEY, Environment} from "../../../token_bridge/__tests__/utils/consts"; +import { + ETH_PRIVATE_KEY, + Environment, +} from "../../../token_bridge/__tests__/utils/consts"; const SAFE_RELAY_DELAY = 10000; const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -export const PRIVATE_KEY = process.env['WALLET_KEY'] || ETH_PRIVATE_KEY; +export const PRIVATE_KEY = process.env["WALLET_KEY"] || ETH_PRIVATE_KEY; export const networkOptions = ["MAINNET", "TESTNET", "DEVNET"]; export const isCI = (): boolean => { - return !!process.env['CI']; -} + return !!process.env["CI"]; +}; export const getNetwork = (): Network => { - const network = process.env['NETWORK'] || ""; - if(!(networkOptions.includes(network))) throw Error(`Invalid Network: ${network}. Options ${networkOptions.join(", ")}`); - return network as Network; -} + const network = process.env["NETWORK"] || ""; + if (!networkOptions.includes(network)) + throw Error( + `Invalid Network: ${network}. Options ${networkOptions.join(", ")}` + ); + return network as Network; +}; export const generateRandomString = (length: number) => { let randomString = ""; @@ -36,7 +42,7 @@ export const getArbitraryBytes32 = (): string => { return ethers.utils.hexlify( ethers.utils.toUtf8Bytes(generateRandomString(32)) ); -} +}; export async function waitForRelay(quantity?: number) { await new Promise((resolve) => @@ -45,36 +51,48 @@ export async function waitForRelay(quantity?: number) { } export const getGuardianRPC = (network: Network, ci: boolean) => { - return process.env.GUARDIAN_RPC || (ci ? "http://guardian:7071" : network == "DEVNET" ? "http://localhost:7071" : network == "TESTNET" ? "https://wormhole-v2-testnet-api.certus.one" : "https://wormhole-v2-mainnet-api.certus.one"); -} + return ( + process.env.GUARDIAN_RPC || + (ci + ? "http://guardian:7071" + : network == "DEVNET" + ? "http://localhost:7071" + : network == "TESTNET" + ? "https://wormhole-v2-testnet-api.certus.one" + : "https://wormhole-v2-mainnet-api.certus.one") + ); +}; // These variables also live in testing/solana-test-validator/sdk-tests/helpers // Ideally we find a better home for these (probably somewhere in the SDK) // These are used to mock a devnet/CI guardian -export const GUARDIAN_KEYS = process.env.GUARDIAN_KEY ? [process.env.GUARDIAN_KEY] : [ - "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0", - "c3b2e45c422a1602333a64078aeb42637370b0f48fe385f9cfa6ad54a8e0c47e", - "9f790d3f08bc4b5cd910d4278f3deb406e57bb5e924906ccd52052bb078ccd47", - "b20cc49d6f2c82a5e6519015fc18aa3e562867f85f872c58f1277cfbd2a0c8e4", - "eded5a2fdcb5bbbfa5b07f2a91393813420e7ac30a72fc935b6df36f8294b855", - "00d39587c3556f289677a837c7f3c0817cb7541ce6e38a243a4bdc761d534c5e", - "da534d61a8da77b232f3a2cee55c0125e2b3e33a5cd8247f3fe9e72379445c3b", - "cdbabfc2118eb00bc62c88845f3bbd03cb67a9e18a055101588ca9b36387006c", - "c83d36423820e7350428dc4abe645cb2904459b7d7128adefe16472fdac397ba", - "1cbf4e1388b81c9020500fefc83a7a81f707091bb899074db1bfce4537428112", - "17646a6ba14a541957fc7112cc973c0b3f04fce59484a92c09bb45a0b57eb740", - "eb94ff04accbfc8195d44b45e7c7da4c6993b2fbbfc4ef166a7675a905df9891", - "053a6527124b309d914a47f5257a995e9b0ad17f14659f90ed42af5e6e262b6a", - "3fbf1e46f6da69e62aed5670f279e818889aa7d8f1beb7fd730770fd4f8ea3d7", - "53b05697596ba04067e40be8100c9194cbae59c90e7870997de57337497172e9", - "4e95cb2ff3f7d5e963631ad85c28b1b79cb370f21c67cbdd4c2ffb0bf664aa06", - "01b8c448ce2c1d43cfc5938d3a57086f88e3dc43bb8b08028ecb7a7924f4676f", - "1db31a6ba3bcd54d2e8a64f8a2415064265d291593450c6eb7e9a6a986bd9400", - "70d8f1c9534a0ab61a020366b831a494057a289441c07be67e4288c44bc6cd5d", -]; -export const GUARDIAN_SET_INDEX = process.env.GUARDIAN_SET_INDEX ? parseInt(process.env.GUARDIAN_SET_INDEX) : 0; -export const GOVERNANCE_EMITTER_ADDRESS = process.env.GOVERNANCE_EMITTER_ADDRESS || new PublicKey( - "11111111111111111111111111111115" -).toBuffer().toString("hex"); - +export const GUARDIAN_KEYS = process.env.GUARDIAN_KEY + ? [process.env.GUARDIAN_KEY] + : [ + "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0", + "c3b2e45c422a1602333a64078aeb42637370b0f48fe385f9cfa6ad54a8e0c47e", + "9f790d3f08bc4b5cd910d4278f3deb406e57bb5e924906ccd52052bb078ccd47", + "b20cc49d6f2c82a5e6519015fc18aa3e562867f85f872c58f1277cfbd2a0c8e4", + "eded5a2fdcb5bbbfa5b07f2a91393813420e7ac30a72fc935b6df36f8294b855", + "00d39587c3556f289677a837c7f3c0817cb7541ce6e38a243a4bdc761d534c5e", + "da534d61a8da77b232f3a2cee55c0125e2b3e33a5cd8247f3fe9e72379445c3b", + "cdbabfc2118eb00bc62c88845f3bbd03cb67a9e18a055101588ca9b36387006c", + "c83d36423820e7350428dc4abe645cb2904459b7d7128adefe16472fdac397ba", + "1cbf4e1388b81c9020500fefc83a7a81f707091bb899074db1bfce4537428112", + "17646a6ba14a541957fc7112cc973c0b3f04fce59484a92c09bb45a0b57eb740", + "eb94ff04accbfc8195d44b45e7c7da4c6993b2fbbfc4ef166a7675a905df9891", + "053a6527124b309d914a47f5257a995e9b0ad17f14659f90ed42af5e6e262b6a", + "3fbf1e46f6da69e62aed5670f279e818889aa7d8f1beb7fd730770fd4f8ea3d7", + "53b05697596ba04067e40be8100c9194cbae59c90e7870997de57337497172e9", + "4e95cb2ff3f7d5e963631ad85c28b1b79cb370f21c67cbdd4c2ffb0bf664aa06", + "01b8c448ce2c1d43cfc5938d3a57086f88e3dc43bb8b08028ecb7a7924f4676f", + "1db31a6ba3bcd54d2e8a64f8a2415064265d291593450c6eb7e9a6a986bd9400", + "70d8f1c9534a0ab61a020366b831a494057a289441c07be67e4288c44bc6cd5d", + ]; +export const GUARDIAN_SET_INDEX = process.env.GUARDIAN_SET_INDEX + ? parseInt(process.env.GUARDIAN_SET_INDEX) + : 0; +export const GOVERNANCE_EMITTER_ADDRESS = + process.env.GOVERNANCE_EMITTER_ADDRESS || + new PublicKey("11111111111111111111111111111115").toBuffer().toString("hex"); diff --git a/sdk/js/src/relayer/relayer/helpers.ts b/sdk/js/src/relayer/relayer/helpers.ts index 2a865cfec..a929c0cf4 100644 --- a/sdk/js/src/relayer/relayer/helpers.ts +++ b/sdk/js/src/relayer/relayer/helpers.ts @@ -21,7 +21,7 @@ import { VaaKey, DeliveryOverrideArgs, parseForwardFailureError, - parseRefundStatus + parseRefundStatus, } from "../structs"; import { DeliveryProvider, diff --git a/sdk/js/src/relayer/relayer/send.ts b/sdk/js/src/relayer/relayer/send.ts index 7ec6da4ce..60084490f 100644 --- a/sdk/js/src/relayer/relayer/send.ts +++ b/sdk/js/src/relayer/relayer/send.ts @@ -19,7 +19,7 @@ export type SendOptionalParams = { chainId?: ChainId; emitterAddress: string; sequenceNumber: ethers.BigNumberish; - } + }, ]; deliveryProviderAddress?: string; wormholeRelayerAddress?: string; diff --git a/sdk/js/src/relayer/structs.ts b/sdk/js/src/relayer/structs.ts index f9bbc2caa..88cd53d87 100644 --- a/sdk/js/src/relayer/structs.ts +++ b/sdk/js/src/relayer/structs.ts @@ -7,7 +7,7 @@ export enum RelayerPayloadId { } export enum ExecutionInfoVersion { - EVM_V1 = 0 + EVM_V1 = 0, } export enum DeliveryStatus { @@ -26,16 +26,21 @@ export enum RefundStatus { RefundFail = "Refund Fail", CrossChainRefundSent = "Cross Chain Refund Sent", CrossChainRefundFailProviderNotSupported = "Cross Chain Refund Fail - Provider does not support the refund chain", - CrossChainRefundFailNotEnough = "Cross Chain Refund Fail - Refund too low for cross chain refund" + CrossChainRefundFailNotEnough = "Cross Chain Refund Fail - Refund too low for cross chain refund", } export function parseRefundStatus(index: number) { - return index === 0 ? RefundStatus.RefundSent - : index === 1 ? RefundStatus.RefundFail - : index === 2 ? RefundStatus.CrossChainRefundSent - : index === 3 ? RefundStatus.CrossChainRefundFailProviderNotSupported - : index === 4 ? RefundStatus.CrossChainRefundFailNotEnough - : RefundStatus.CrossChainRefundFailProviderNotSupported; + return index === 0 + ? RefundStatus.RefundSent + : index === 1 + ? RefundStatus.RefundFail + : index === 2 + ? RefundStatus.CrossChainRefundSent + : index === 3 + ? RefundStatus.CrossChainRefundFailProviderNotSupported + : index === 4 + ? RefundStatus.CrossChainRefundFailNotEnough + : RefundStatus.CrossChainRefundFailProviderNotSupported; } export interface VaaKey { @@ -184,7 +189,7 @@ export function parseWormholeRelayerSend(bytes: Buffer): DeliveryInstruction { refundDeliveryProvider, sourceDeliveryProvider, senderAddress, - vaaKeys: messages + vaaKeys: messages, }; } @@ -200,23 +205,22 @@ function parseVaaKey(bytes: Buffer, idx: number): [VaaKey, number] { const version = bytes.readUInt8(idx); idx += 1; - const chainId = bytes.readUInt16BE(idx); - idx += 2; - const emitterAddress = bytes.slice(idx, idx + 32); - idx += 32; - const sequence = ethers.BigNumber.from( - Uint8Array.prototype.subarray.call(bytes, idx, idx + 8) - ); - idx += 8; - return [ - { - chainId, - emitterAddress, - sequence, - }, - idx, - ]; - + const chainId = bytes.readUInt16BE(idx); + idx += 2; + const emitterAddress = bytes.slice(idx, idx + 32); + idx += 32; + const sequence = ethers.BigNumber.from( + Uint8Array.prototype.subarray.call(bytes, idx, idx + 8) + ); + idx += 8; + return [ + { + chainId, + emitterAddress, + sequence, + }, + idx, + ]; } export function parseEVMExecutionInfoV1( @@ -226,7 +230,7 @@ export function parseEVMExecutionInfoV1( idx += 31; const version = bytes.readUInt8(idx); idx += 1; - if(version !== ExecutionInfoVersion.EVM_V1) { + if (version !== ExecutionInfoVersion.EVM_V1) { throw new Error("Unexpected Execution Info version"); } const gasLimit = ethers.BigNumber.from( @@ -267,11 +271,9 @@ export function parseWormholeRelayerResend( let newEncodedExecutionInfo; [newEncodedExecutionInfo, idx] = parsePayload(bytes, idx); - const newSourceDeliveryProvider = bytes.slice(idx, idx + 32); idx += 32; - const newSenderAddress = bytes.slice(idx, idx + 32); idx += 32; return { @@ -280,14 +282,12 @@ export function parseWormholeRelayerResend( newRequestedReceiverValue, newEncodedExecutionInfo, newSourceDeliveryProvider, - newSenderAddress + newSenderAddress, }; } -export function executionInfoToString( - encodedExecutionInfo: Buffer -): string { - const [parsed,] = parseEVMExecutionInfoV1(encodedExecutionInfo, 0) +export function executionInfoToString(encodedExecutionInfo: Buffer): string { + const [parsed] = parseEVMExecutionInfoV1(encodedExecutionInfo, 0); return `Gas limit: ${parsed.gasLimit}, Target chain refund per unit gas unused: ${parsed.targetChainRefundPerGasUnused}`; } @@ -311,11 +311,11 @@ export function deliveryInstructionsPrintable( } export function vaaKeyPrintable(ix: VaaKey): StringLeaves { - return { - chainId: ix.chainId?.toString(), - emitterAddress: ix.emitterAddress?.toString("hex"), - sequence: ix.sequence?.toString(), - }; + return { + chainId: ix.chainId?.toString(), + emitterAddress: ix.emitterAddress?.toString("hex"), + sequence: ix.sequence?.toString(), + }; } export function redeliveryInstructionPrintable( @@ -327,7 +327,7 @@ export function redeliveryInstructionPrintable( newRequestedReceiverValue: ix.newRequestedReceiverValue.toString(), newEncodedExecutionInfo: executionInfoToString(ix.newEncodedExecutionInfo), newSourceDeliveryProvider: ix.newSourceDeliveryProvider.toString("hex"), - newSenderAddress: ix.newSenderAddress.toString("hex") + newSenderAddress: ix.newSenderAddress.toString("hex"), }; } @@ -353,13 +353,11 @@ export function packOverrides(overrides: DeliveryOverrideArgs): string { return "0x" + packed; } -export function parseForwardFailureError( - bytes: Buffer -): string { +export function parseForwardFailureError(bytes: Buffer): string { let idx = 4; idx += 32; - if(bytes.length <= idx) { - return `Delivery Provider failed in performing forward` + if (bytes.length <= idx) { + return `Delivery Provider failed in performing forward`; } try { const amountOfFunds = ethers.BigNumber.from( @@ -369,12 +367,12 @@ export function parseForwardFailureError( const amountOfFundsNeeded = ethers.BigNumber.from( Uint8Array.prototype.subarray.call(bytes, idx, idx + 32) ); - return `Not enough funds leftover for forward: Had ${ethers.utils.formatEther(amountOfFunds)} and needed ${ethers.utils.formatEther(amountOfFundsNeeded)}.` - + return `Not enough funds leftover for forward: Had ${ethers.utils.formatEther( + amountOfFunds + )} and needed ${ethers.utils.formatEther(amountOfFundsNeeded)}.`; } catch (err) { - return `Delivery Provider unexpectedly failed in performing forward` + return `Delivery Provider unexpectedly failed in performing forward`; } - } export function parseOverrideInfoFromDeliveryEvent( @@ -397,7 +395,7 @@ export function parseOverrideInfoFromDeliveryEvent( return { newReceiverValue, newExecutionInfo, - redeliveryHash + redeliveryHash, }; } diff --git a/sdk/js/src/solana/wormhole/coder/events.ts b/sdk/js/src/solana/wormhole/coder/events.ts index a76314112..10abc4072 100644 --- a/sdk/js/src/solana/wormhole/coder/events.ts +++ b/sdk/js/src/solana/wormhole/coder/events.ts @@ -4,7 +4,9 @@ import { IdlEvent } from "../../anchor"; export class WormholeEventsCoder implements EventCoder { constructor(_idl: Idl) {} - decode>(_log: string): Event | null { + decode>( + _log: string + ): Event | null { throw new Error("Wormhole program does not have events"); } } diff --git a/sdk/js/src/solana/wormhole/coder/idl.ts b/sdk/js/src/solana/wormhole/coder/idl.ts index 93b4d28b1..9460aae3b 100644 --- a/sdk/js/src/solana/wormhole/coder/idl.ts +++ b/sdk/js/src/solana/wormhole/coder/idl.ts @@ -2,111 +2,111 @@ // // https://github.com/coral-xyz/anchor/blob/master/ts/packages/anchor/src/coder/borsh/idl.ts -import * as borsh from "@coral-xyz/borsh" +import * as borsh from "@coral-xyz/borsh"; import { Layout } from "buffer-layout"; import { IdlField, IdlTypeDef } from "../../anchor"; import { camelCase } from "lodash"; export class IdlCoder { - public static fieldLayout( - field: { name?: string } & Pick, - types?: IdlTypeDef[] - ): Layout { - const fieldName = - field.name !== undefined ? camelCase(field.name) : undefined; - switch (field.type) { - case "bool": { - return borsh.bool(fieldName); - } - case "u8": { - return borsh.u8(fieldName); - } - case "i8": { - return borsh.i8(fieldName); - } - case "u16": { - return borsh.u16(fieldName); - } - case "i16": { - return borsh.i16(fieldName); - } - case "u32": { - return borsh.u32(fieldName); - } - case "i32": { - return borsh.i32(fieldName); - } - case "f32": { - return borsh.f32(fieldName); - } - case "u64": { - return borsh.u64(fieldName); - } - case "i64": { - return borsh.i64(fieldName); - } - case "f64": { - return borsh.f64(fieldName); - } - case "u128": { - return borsh.u128(fieldName); - } - case "i128": { - return borsh.i128(fieldName); - } - case "u256": { - return borsh.u256(fieldName); - } - case "i256": { - return borsh.i256(fieldName); - } - case "bytes": { - return borsh.vecU8(fieldName); - } - case "string": { - return borsh.str(fieldName); - } - case "publicKey": { - return borsh.publicKey(fieldName); - } - default: { - if ("vec" in field.type) { - return borsh.vec( - IdlCoder.fieldLayout( - { - name: undefined, - type: field.type.vec, - }, - types - ), - fieldName - ); - } else if ("option" in field.type) { - return borsh.option( - IdlCoder.fieldLayout( - { - name: undefined, - type: field.type.option, - }, - types - ), - fieldName - ); - } else if ("array" in field.type) { - let arrayTy = field.type.array[0]; - let arrayLen = field.type.array[1]; - let innerLayout = IdlCoder.fieldLayout( + public static fieldLayout( + field: { name?: string } & Pick, + types?: IdlTypeDef[] + ): Layout { + const fieldName = + field.name !== undefined ? camelCase(field.name) : undefined; + switch (field.type) { + case "bool": { + return borsh.bool(fieldName); + } + case "u8": { + return borsh.u8(fieldName); + } + case "i8": { + return borsh.i8(fieldName); + } + case "u16": { + return borsh.u16(fieldName); + } + case "i16": { + return borsh.i16(fieldName); + } + case "u32": { + return borsh.u32(fieldName); + } + case "i32": { + return borsh.i32(fieldName); + } + case "f32": { + return borsh.f32(fieldName); + } + case "u64": { + return borsh.u64(fieldName); + } + case "i64": { + return borsh.i64(fieldName); + } + case "f64": { + return borsh.f64(fieldName); + } + case "u128": { + return borsh.u128(fieldName); + } + case "i128": { + return borsh.i128(fieldName); + } + case "u256": { + return borsh.u256(fieldName); + } + case "i256": { + return borsh.i256(fieldName); + } + case "bytes": { + return borsh.vecU8(fieldName); + } + case "string": { + return borsh.str(fieldName); + } + case "publicKey": { + return borsh.publicKey(fieldName); + } + default: { + if ("vec" in field.type) { + return borsh.vec( + IdlCoder.fieldLayout( { name: undefined, - type: arrayTy, + type: field.type.vec, }, types - ); - return borsh.array(innerLayout, arrayLen, fieldName); - } else { - throw new Error(`Not yet implemented: ${field}`); - } + ), + fieldName + ); + } else if ("option" in field.type) { + return borsh.option( + IdlCoder.fieldLayout( + { + name: undefined, + type: field.type.option, + }, + types + ), + fieldName + ); + } else if ("array" in field.type) { + let arrayTy = field.type.array[0]; + let arrayLen = field.type.array[1]; + let innerLayout = IdlCoder.fieldLayout( + { + name: undefined, + type: arrayTy, + }, + types + ); + return borsh.array(innerLayout, arrayLen, fieldName); + } else { + throw new Error(`Not yet implemented: ${field}`); } } } - } \ No newline at end of file + } +} diff --git a/sdk/js/src/solana/wormhole/coder/state.ts b/sdk/js/src/solana/wormhole/coder/state.ts index 99a27aa9b..874a581bb 100644 --- a/sdk/js/src/solana/wormhole/coder/state.ts +++ b/sdk/js/src/solana/wormhole/coder/state.ts @@ -9,4 +9,4 @@ export class WormholeStateCoder implements StateCoder { decode(_ix: Buffer): T { throw new Error("Wormhole program does not have state"); } -} \ No newline at end of file +} diff --git a/sdk/js/src/solana/wormhole/coder/types.ts b/sdk/js/src/solana/wormhole/coder/types.ts index 3bc74c97c..79c4c468a 100644 --- a/sdk/js/src/solana/wormhole/coder/types.ts +++ b/sdk/js/src/solana/wormhole/coder/types.ts @@ -1,12 +1,12 @@ import { Idl, TypesCoder } from "@project-serum/anchor"; export class WormholeTypesCoder implements TypesCoder { - constructor(_idl: Idl) {} - - encode(_name: string, _type: T): Buffer { - throw new Error("Wormhole program does not have user-defined types"); - } - decode(_name: string, _typeData: Buffer): T { - throw new Error("Wormhole program does not have user-defined types"); - } - } \ No newline at end of file + constructor(_idl: Idl) {} + + encode(_name: string, _type: T): Buffer { + throw new Error("Wormhole program does not have user-defined types"); + } + decode(_name: string, _typeData: Buffer): T { + throw new Error("Wormhole program does not have user-defined types"); + } +} diff --git a/sdk/js/src/solana/wormhole/instructions/initialize.ts b/sdk/js/src/solana/wormhole/instructions/initialize.ts index 84c03bbb9..02cb1d93a 100644 --- a/sdk/js/src/solana/wormhole/instructions/initialize.ts +++ b/sdk/js/src/solana/wormhole/instructions/initialize.ts @@ -23,11 +23,9 @@ export function createInitializeInstruction( ): TransactionInstruction { const methods = createReadOnlyWormholeProgramInterface( wormholeProgramId - ).methods.initialize( - guardianSetExpirationTime, - new BN(fee.toString()), - [...initialGuardians] - ); + ).methods.initialize(guardianSetExpirationTime, new BN(fee.toString()), [ + ...initialGuardians, + ]); // @ts-ignore return methods._ixFn(...methods._args, { diff --git a/sdk/js/src/solana/wormhole/instructions/verifySignature.ts b/sdk/js/src/solana/wormhole/instructions/verifySignature.ts index 514d851a5..1ff44ce5f 100644 --- a/sdk/js/src/solana/wormhole/instructions/verifySignature.ts +++ b/sdk/js/src/solana/wormhole/instructions/verifySignature.ts @@ -70,7 +70,7 @@ export async function createVerifySignaturesInstructions( for (let i = 0; i < Math.ceil(guardianSignatures.length / batchSize); ++i) { const start = i * batchSize; const end = Math.min(guardianSignatures.length, (i + 1) * batchSize); - + const signatureStatus = new Array(MAX_LEN_GUARDIAN_KEYS).fill(-1); const signatures: Buffer[] = []; const keys: Buffer[] = []; @@ -123,9 +123,10 @@ function createVerifySignaturesInstruction( signatureSet: PublicKeyInitData, signatureStatus: number[] ): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId - ).methods.verifySignatures(signatureStatus); + const methods = + createReadOnlyWormholeProgramInterface( + wormholeProgramId + ).methods.verifySignatures(signatureStatus); // @ts-ignore return methods._ixFn(...methods._args, { diff --git a/sdk/js/src/utils/array.ts b/sdk/js/src/utils/array.ts index 5862dfc12..78329458a 100644 --- a/sdk/js/src/utils/array.ts +++ b/sdk/js/src/utils/array.ts @@ -109,7 +109,7 @@ export const tryUint8ArrayToNative = ( } else if (chainId === CHAIN_ID_XPLA) { return humanAddress("xpla", a.slice(-20)); } else if (chainId === CHAIN_ID_SEI) { - return humanAddress("sei", a.slice(-20)); + return humanAddress("sei", a.slice(-20)); } else if (chainId === CHAIN_ID_NEAR) { throw Error("uint8ArrayToNative: Use tryHexToNativeStringNear instead."); } else if (chainId === CHAIN_ID_OSMOSIS) { diff --git a/sdk/js/src/utils/consts.ts b/sdk/js/src/utils/consts.ts index 99578642b..76e0debd4 100644 --- a/sdk/js/src/utils/consts.ts +++ b/sdk/js/src/utils/consts.ts @@ -63,12 +63,14 @@ export const EVMChainNames: ReadonlyArray = [ ] as const; export type EVMChainName = (typeof EVMChainNames)[number]; - /* * * All the Solana-based chain names that Wormhole supports */ -export const SolanaChainNames: ReadonlyArray = ["solana", "pythnet"] as const; +export const SolanaChainNames: ReadonlyArray = [ + "solana", + "pythnet", +] as const; export type SolanaChainName = (typeof SolanaChainNames)[number]; export const CosmWasmChainNames: ReadonlyArray = [ @@ -81,7 +83,10 @@ export const CosmWasmChainNames: ReadonlyArray = [ export type CosmWasmChainName = (typeof CosmWasmChainNames)[number]; // TODO: why? these are dupe of entries in CosmWasm -export const TerraChainNames: ReadonlyArray = ["terra", "terra2"] as const; +export const TerraChainNames: ReadonlyArray = [ + "terra", + "terra2", +] as const; export type TerraChainName = (typeof TerraChainNames)[number]; export type Contracts = { @@ -810,7 +815,7 @@ export function isEVMChain( chain: ChainId | ChainName ): chain is EVMChainId | EVMChainName { const chainName = coalesceChainName(chain); - return EVMChainNames.includes(chainName) + return EVMChainNames.includes(chainName); } export function isCosmWasmChain( diff --git a/sdk/js/src/vaa/generic.ts b/sdk/js/src/vaa/generic.ts index 0430fe60c..7dbabf3a3 100644 --- a/sdk/js/src/vaa/generic.ts +++ b/sdk/js/src/vaa/generic.ts @@ -384,7 +384,7 @@ function serialiseCoreContractUpgrade(payload: CoreContractUpgrade): string { } export interface PortalContractUpgrade< - Module extends "NFTBridge" | "TokenBridge" + Module extends "NFTBridge" | "TokenBridge", > { module: Module; type: "ContractUpgrade"; @@ -394,7 +394,7 @@ export interface PortalContractUpgrade< // Parse a portal contract upgrade payload function portalContractUpgradeParser< - Module extends "NFTBridge" | "TokenBridge" + Module extends "NFTBridge" | "TokenBridge", >(module: Module): P> { return new P( new Parser() @@ -423,7 +423,7 @@ function portalContractUpgradeParser< } function serialisePortalContractUpgrade< - Module extends "NFTBridge" | "TokenBridge" + Module extends "NFTBridge" | "TokenBridge", >(payload: PortalContractUpgrade): string { const body = [ encode("bytes32", encodeString(payload.module)), @@ -438,7 +438,7 @@ function serialisePortalContractUpgrade< // Registrations export interface PortalRegisterChain< - Module extends "NFTBridge" | "TokenBridge" + Module extends "NFTBridge" | "TokenBridge", > { module: Module; type: "RegisterChain"; @@ -479,7 +479,7 @@ function portalRegisterChainParser( } function serialisePortalRegisterChain< - Module extends "NFTBridge" | "TokenBridge" + Module extends "NFTBridge" | "TokenBridge", >(payload: PortalRegisterChain): string { const body = [ encode("bytes32", encodeString(payload.module)),