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
This commit is contained in:
parent
f5987a334f
commit
6309b321e8
|
@ -394,3 +394,11 @@ jobs:
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- run: chmod 755 ./scripts/check-npm-package-scopes.sh
|
- run: chmod 755 ./scripts/check-npm-package-scopes.sh
|
||||||
- run: ./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
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
sdk/js/src/ethers-contracts
|
|
@ -115,7 +115,7 @@ export async function execute_algorand(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "WormholeRelayer":
|
case "WormholeRelayer":
|
||||||
throw Error("Wormhole Relayer not supported on Algorand");
|
throw Error("Wormhole Relayer not supported on Algorand");
|
||||||
default:
|
default:
|
||||||
target_contract = impossible(payload);
|
target_contract = impossible(payload);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ export const submit = async (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "WormholeRelayer":
|
case "WormholeRelayer":
|
||||||
throw Error("Wormhole Relayer not supported on Sei");
|
throw Error("Wormhole Relayer not supported on Sei");
|
||||||
default:
|
default:
|
||||||
target_contract = impossible(payload);
|
target_contract = impossible(payload);
|
||||||
execute_msg = impossible(payload);
|
execute_msg = impossible(payload);
|
||||||
|
|
|
@ -199,7 +199,7 @@ export const submit = async (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "WormholeRelayer":
|
case "WormholeRelayer":
|
||||||
throw Error("Wormhole Relayer not supported on Sui");
|
throw Error("Wormhole Relayer not supported on Sui");
|
||||||
default:
|
default:
|
||||||
impossible(payload);
|
impossible(payload);
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,14 +311,14 @@ export const isSameType = (a: string, b: string) => {
|
||||||
|
|
||||||
export const isSuiCreateEvent = <
|
export const isSuiCreateEvent = <
|
||||||
T extends NonNullable<SuiTransactionBlockResponse["objectChanges"]>[number],
|
T extends NonNullable<SuiTransactionBlockResponse["objectChanges"]>[number],
|
||||||
K extends Extract<T, { type: "created" }>
|
K extends Extract<T, { type: "created" }>,
|
||||||
>(
|
>(
|
||||||
event: T
|
event: T
|
||||||
): event is K => event?.type === "created";
|
): event is K => event?.type === "created";
|
||||||
|
|
||||||
export const isSuiPublishEvent = <
|
export const isSuiPublishEvent = <
|
||||||
T extends NonNullable<SuiTransactionBlockResponse["objectChanges"]>[number],
|
T extends NonNullable<SuiTransactionBlockResponse["objectChanges"]>[number],
|
||||||
K extends Extract<T, { type: "published" }>
|
K extends Extract<T, { type: "published" }>,
|
||||||
>(
|
>(
|
||||||
event: T
|
event: T
|
||||||
): event is K => event?.type === "published";
|
): event is K => event?.type === "published";
|
||||||
|
|
|
@ -82,8 +82,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
describe: "Module to register",
|
describe: "Module to register",
|
||||||
choices: ["NFTBridge", "TokenBridge", "WormholeRelayer"],
|
choices: ["NFTBridge", "TokenBridge", "WormholeRelayer"],
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
} as const)
|
} as const),
|
||||||
,
|
|
||||||
(argv) => {
|
(argv) => {
|
||||||
const module = argv["module"];
|
const module = argv["module"];
|
||||||
assertChain(argv.chain);
|
assertChain(argv.chain);
|
||||||
|
@ -272,7 +271,7 @@ export const builder = function (y: typeof yargs) {
|
||||||
describe: "Address of the delivery provider contract",
|
describe: "Address of the delivery provider contract",
|
||||||
type: "string",
|
type: "string",
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
(argv) => {
|
(argv) => {
|
||||||
assertChain(argv.chain);
|
assertChain(argv.chain);
|
||||||
|
@ -280,7 +279,10 @@ export const builder = function (y: typeof yargs) {
|
||||||
module: "WormholeRelayer",
|
module: "WormholeRelayer",
|
||||||
type: "SetDefaultDeliveryProvider",
|
type: "SetDefaultDeliveryProvider",
|
||||||
chain: toChainId(argv["chain"]),
|
chain: toChainId(argv["chain"]),
|
||||||
relayProviderAddress: parseAddress(argv["chain"], argv["delivery-provider-address"])
|
relayProviderAddress: parseAddress(
|
||||||
|
argv["chain"],
|
||||||
|
argv["delivery-provider-address"]
|
||||||
|
),
|
||||||
};
|
};
|
||||||
let v = makeVAA(
|
let v = makeVAA(
|
||||||
GOVERNANCE_CHAIN,
|
GOVERNANCE_CHAIN,
|
||||||
|
|
|
@ -2,12 +2,8 @@ import {
|
||||||
CHAINS,
|
CHAINS,
|
||||||
ChainName,
|
ChainName,
|
||||||
assertChain,
|
assertChain,
|
||||||
|
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
} from "@certusone/wormhole-sdk/lib/esm/utils/consts";
|
||||||
import {
|
import { relayer, Network } from "@certusone/wormhole-sdk";
|
||||||
relayer,
|
|
||||||
Network
|
|
||||||
} from "@certusone/wormhole-sdk"
|
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
import { CONTRACTS, NETWORKS } from "../consts";
|
import { CONTRACTS, NETWORKS } from "../consts";
|
||||||
import { assertNetwork } from "../utils";
|
import { assertNetwork } from "../utils";
|
||||||
|
@ -15,7 +11,8 @@ import { impossible } from "../vaa";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
|
|
||||||
export const command = "status <network> <chain> <tx>";
|
export const command = "status <network> <chain> <tx>";
|
||||||
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) =>
|
export const builder = (y: typeof yargs) =>
|
||||||
y
|
y
|
||||||
.positional("network", {
|
.positional("network", {
|
||||||
|
@ -40,8 +37,9 @@ export const handler = async (
|
||||||
assertNetwork(network);
|
assertNetwork(network);
|
||||||
const chain = argv.chain;
|
const chain = argv.chain;
|
||||||
assertChain(chain);
|
assertChain(chain);
|
||||||
|
|
||||||
const addr = relayer.RELAYER_CONTRACTS[network][chain]?.wormholeRelayerAddress;
|
const addr =
|
||||||
|
relayer.RELAYER_CONTRACTS[network][chain]?.wormholeRelayerAddress;
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
throw new Error(`Wormhole Relayer not deployed on ${chain} in ${network}`);
|
throw new Error(`Wormhole Relayer not deployed on ${chain} in ${network}`);
|
||||||
}
|
}
|
||||||
|
@ -49,11 +47,20 @@ export const handler = async (
|
||||||
const sourceRPC = NETWORKS[network as Network][chain as ChainName].rpc;
|
const sourceRPC = NETWORKS[network as Network][chain as ChainName].rpc;
|
||||||
const sourceChainProvider = new ethers.providers.JsonRpcProvider(sourceRPC);
|
const sourceChainProvider = new ethers.providers.JsonRpcProvider(sourceRPC);
|
||||||
const targetChainProviders = new Map<ChainName, ethers.providers.Provider>();
|
const targetChainProviders = new Map<ChainName, ethers.providers.Provider>();
|
||||||
for(const key in NETWORKS[network]) {
|
for (const key in NETWORKS[network]) {
|
||||||
targetChainProviders.set(key as ChainName, new ethers.providers.JsonRpcProvider(NETWORKS[network][key as ChainName].rpc));
|
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));
|
console.log(relayer.stringifyWormholeRelayerInfo(info));
|
||||||
};
|
};
|
||||||
|
|
|
@ -123,9 +123,8 @@ export const addSetupCommands: YargsAddCommandsFn = (y: typeof yargs) =>
|
||||||
// Get token bridge state object ID
|
// Get token bridge state object ID
|
||||||
const tokenBridgeStateObjectId = getCreatedObjects(
|
const tokenBridgeStateObjectId = getCreatedObjects(
|
||||||
tokenBridgeInitRes
|
tokenBridgeInitRes
|
||||||
).find((e) =>
|
).find((e) => isSameType(e.type, `${tokenBridgePackageId}::state::State`))
|
||||||
isSameType(e.type, `${tokenBridgePackageId}::state::State`)
|
?.objectId;
|
||||||
)?.objectId;
|
|
||||||
if (!tokenBridgeStateObjectId) {
|
if (!tokenBridgeStateObjectId) {
|
||||||
throw new Error("Couldn't find token bridge state object ID.");
|
throw new Error("Couldn't find token bridge state object ID.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,11 @@ import * as sui from "./cmds/sui";
|
||||||
import * as verifyVaa from "./cmds/verifyVaa";
|
import * as verifyVaa from "./cmds/verifyVaa";
|
||||||
import * as status from "./cmds/status";
|
import * as status from "./cmds/status";
|
||||||
|
|
||||||
|
|
||||||
const MD_TAG = "<!--CLI_USAGE-->";
|
const MD_TAG = "<!--CLI_USAGE-->";
|
||||||
|
|
||||||
async function getHelpText(cmd: any): Promise<string> {
|
async function getHelpText(cmd: any): Promise<string> {
|
||||||
// Note that `yargs` is called as a function to produce a fresh copy.
|
// 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.
|
// other commands is accumulated from repeat calls.
|
||||||
return await cmd.builder(yargs()).scriptName(`worm ${cmd.command}`).getHelp();
|
return await cmd.builder(yargs()).scriptName(`worm ${cmd.command}`).getHelp();
|
||||||
}
|
}
|
||||||
|
@ -41,14 +40,15 @@ async function getHelpText(cmd: any): Promise<string> {
|
||||||
submit,
|
submit,
|
||||||
sui,
|
sui,
|
||||||
verifyVaa,
|
verifyVaa,
|
||||||
status
|
status,
|
||||||
];
|
];
|
||||||
|
|
||||||
const helpOutputs: Buffer[] = [];
|
const helpOutputs: Buffer[] = [];
|
||||||
for (const cmd of cmds) {
|
for (const cmd of cmds) {
|
||||||
const helpText = await getHelpText(cmd);
|
const helpText = await getHelpText(cmd);
|
||||||
|
|
||||||
helpOutputs.push(Buffer.from(`
|
helpOutputs.push(
|
||||||
|
Buffer.from(`
|
||||||
<details>
|
<details>
|
||||||
<summary> ${cmd.command} </summary>
|
<summary> ${cmd.command} </summary>
|
||||||
|
|
||||||
|
@ -56,11 +56,10 @@ async function getHelpText(cmd: any): Promise<string> {
|
||||||
${helpText}
|
${helpText}
|
||||||
\`\`\`
|
\`\`\`
|
||||||
</details>
|
</details>
|
||||||
`))
|
`)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const f = fs.readFileSync("README.md");
|
const f = fs.readFileSync("README.md");
|
||||||
const startIdx = f.indexOf(MD_TAG, 0);
|
const startIdx = f.indexOf(MD_TAG, 0);
|
||||||
const stopIdx = f.indexOf(MD_TAG, startIdx + 1);
|
const stopIdx = f.indexOf(MD_TAG, startIdx + 1);
|
||||||
|
@ -68,7 +67,7 @@ ${helpText}
|
||||||
const head = f.subarray(0, startIdx + MD_TAG.length);
|
const head = f.subarray(0, startIdx + MD_TAG.length);
|
||||||
const tail = f.subarray(stopIdx, f.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());
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
getEmitterAddressEth,
|
getEmitterAddressEth,
|
||||||
getEmitterAddressNear,
|
getEmitterAddressNear,
|
||||||
getEmitterAddressSolana,
|
getEmitterAddressSolana,
|
||||||
getEmitterAddressTerra
|
getEmitterAddressTerra,
|
||||||
} from "@certusone/wormhole-sdk/lib/esm/bridge/getEmitterAddress";
|
} from "@certusone/wormhole-sdk/lib/esm/bridge/getEmitterAddress";
|
||||||
|
|
||||||
export async function getEmitterAddress(
|
export async function getEmitterAddress(
|
||||||
|
|
|
@ -29,10 +29,10 @@ console.warn = function (x: string) {
|
||||||
//
|
//
|
||||||
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
||||||
interface BigInt {
|
interface BigInt {
|
||||||
/** Convert to BigInt to string form in JSON.stringify */
|
/** Convert to BigInt to string form in JSON.stringify */
|
||||||
toJSON: () => string;
|
toJSON: () => string;
|
||||||
}
|
}
|
||||||
// Without this JSON.stringify() blows up
|
// Without this JSON.stringify() blows up
|
||||||
(BigInt.prototype as any).toJSON = function () {
|
(BigInt.prototype as any).toJSON = function () {
|
||||||
return this.toString();
|
return this.toString();
|
||||||
};
|
};
|
||||||
|
|
|
@ -143,7 +143,7 @@ export async function execute_terra(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "WormholeRelayer":
|
case "WormholeRelayer":
|
||||||
throw Error("Wormhole Relayer not supported on Terra");
|
throw Error("Wormhole Relayer not supported on Terra");
|
||||||
default:
|
default:
|
||||||
target_contract = impossible(payload);
|
target_contract = impossible(payload);
|
||||||
execute_msg = impossible(payload);
|
execute_msg = impossible(payload);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -139,7 +139,7 @@ export async function execute_xpla(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "WormholeRelayer":
|
case "WormholeRelayer":
|
||||||
throw Error("Wormhole Relayer not supported on Xpla");
|
throw Error("Wormhole Relayer not supported on Xpla");
|
||||||
default:
|
default:
|
||||||
target_contract = impossible(payload);
|
target_contract = impossible(payload);
|
||||||
execute_msg = impossible(payload);
|
execute_msg = impossible(payload);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { ChainId } from "../../utils";
|
||||||
|
|
||||||
export const upgradeGuardianSet = (
|
export const upgradeGuardianSet = (
|
||||||
coreBridgeAddress: string,
|
coreBridgeAddress: string,
|
||||||
vaa: Uint8Array,
|
vaa: Uint8Array
|
||||||
): Types.EntryFunctionPayload => {
|
): Types.EntryFunctionPayload => {
|
||||||
if (!coreBridgeAddress) throw new Error("Need core bridge address.");
|
if (!coreBridgeAddress) throw new Error("Need core bridge address.");
|
||||||
return {
|
return {
|
||||||
|
@ -22,12 +22,17 @@ export const initWormhole = (
|
||||||
chainId: ChainId,
|
chainId: ChainId,
|
||||||
governanceChainId: number,
|
governanceChainId: number,
|
||||||
governanceContract: Uint8Array,
|
governanceContract: Uint8Array,
|
||||||
initialGuardian: Uint8Array,
|
initialGuardian: Uint8Array
|
||||||
): Types.EntryFunctionPayload => {
|
): Types.EntryFunctionPayload => {
|
||||||
if (!coreBridgeAddress) throw new Error("Need core bridge address.");
|
if (!coreBridgeAddress) throw new Error("Need core bridge address.");
|
||||||
return {
|
return {
|
||||||
function: `${coreBridgeAddress}::wormhole::init`,
|
function: `${coreBridgeAddress}::wormhole::init`,
|
||||||
type_arguments: [],
|
type_arguments: [],
|
||||||
arguments: [chainId, governanceChainId, governanceContract, initialGuardian],
|
arguments: [
|
||||||
|
chainId,
|
||||||
|
governanceChainId,
|
||||||
|
governanceContract,
|
||||||
|
initialGuardian,
|
||||||
|
],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,16 +17,16 @@ import {
|
||||||
export const attestToken = (
|
export const attestToken = (
|
||||||
tokenBridgeAddress: string,
|
tokenBridgeAddress: string,
|
||||||
tokenChain: ChainId | ChainName,
|
tokenChain: ChainId | ChainName,
|
||||||
tokenAddress: string,
|
tokenAddress: string
|
||||||
): Types.EntryFunctionPayload => {
|
): Types.EntryFunctionPayload => {
|
||||||
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
||||||
const assetType = getAssetFullyQualifiedType(
|
const assetType = getAssetFullyQualifiedType(
|
||||||
tokenBridgeAddress,
|
tokenBridgeAddress,
|
||||||
coalesceChainId(tokenChain),
|
coalesceChainId(tokenChain),
|
||||||
tokenAddress,
|
tokenAddress
|
||||||
);
|
);
|
||||||
if (!assetType) throw new Error("Invalid asset address.");
|
if (!assetType) throw new Error("Invalid asset address.");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
function: `${tokenBridgeAddress}::attest_token::attest_token_entry`,
|
function: `${tokenBridgeAddress}::attest_token::attest_token_entry`,
|
||||||
type_arguments: [assetType],
|
type_arguments: [assetType],
|
||||||
|
@ -40,7 +40,7 @@ export const completeTransfer = async (
|
||||||
client: AptosClient,
|
client: AptosClient,
|
||||||
tokenBridgeAddress: string,
|
tokenBridgeAddress: string,
|
||||||
transferVAA: Uint8Array,
|
transferVAA: Uint8Array,
|
||||||
feeRecipient: string,
|
feeRecipient: string
|
||||||
): Promise<Types.EntryFunctionPayload> => {
|
): Promise<Types.EntryFunctionPayload> => {
|
||||||
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ export const completeTransfer = async (
|
||||||
if (parsedVAA.ToChain !== CHAIN_ID_APTOS) {
|
if (parsedVAA.ToChain !== CHAIN_ID_APTOS) {
|
||||||
throw new Error("Transfer is not destined for Aptos");
|
throw new Error("Transfer is not destined for Aptos");
|
||||||
}
|
}
|
||||||
|
|
||||||
assertChain(parsedVAA.FromChain);
|
assertChain(parsedVAA.FromChain);
|
||||||
const assetType =
|
const assetType =
|
||||||
parsedVAA.FromChain === CHAIN_ID_APTOS
|
parsedVAA.FromChain === CHAIN_ID_APTOS
|
||||||
|
@ -78,7 +78,7 @@ export const completeTransfer = async (
|
||||||
export const completeTransferAndRegister = async (
|
export const completeTransferAndRegister = async (
|
||||||
client: AptosClient,
|
client: AptosClient,
|
||||||
tokenBridgeAddress: string,
|
tokenBridgeAddress: string,
|
||||||
transferVAA: Uint8Array,
|
transferVAA: Uint8Array
|
||||||
): Promise<Types.EntryFunctionPayload> => {
|
): Promise<Types.EntryFunctionPayload> => {
|
||||||
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ export const completeTransferAndRegister = async (
|
||||||
if (parsedVAA.ToChain !== CHAIN_ID_APTOS) {
|
if (parsedVAA.ToChain !== CHAIN_ID_APTOS) {
|
||||||
throw new Error("Transfer is not destined for Aptos");
|
throw new Error("Transfer is not destined for Aptos");
|
||||||
}
|
}
|
||||||
|
|
||||||
assertChain(parsedVAA.FromChain);
|
assertChain(parsedVAA.FromChain);
|
||||||
const assetType =
|
const assetType =
|
||||||
parsedVAA.FromChain === CHAIN_ID_APTOS
|
parsedVAA.FromChain === CHAIN_ID_APTOS
|
||||||
|
@ -117,21 +117,23 @@ export const completeTransferWithPayload = (
|
||||||
_tokenBridgeAddress: string,
|
_tokenBridgeAddress: string,
|
||||||
_tokenChain: ChainId | ChainName,
|
_tokenChain: ChainId | ChainName,
|
||||||
_tokenAddress: string,
|
_tokenAddress: string,
|
||||||
_vaa: Uint8Array,
|
_vaa: Uint8Array
|
||||||
): Types.EntryFunctionPayload => {
|
): 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.
|
* ID and address to the sender's account.
|
||||||
*
|
*
|
||||||
* The bytecode was compiled from the following Move code:
|
* The bytecode was compiled from the following Move code:
|
||||||
* ```move
|
* ```move
|
||||||
* script {
|
* script {
|
||||||
* use aptos_framework::coin;
|
* use aptos_framework::coin;
|
||||||
* use aptos_framework::signer;
|
* use aptos_framework::signer;
|
||||||
*
|
*
|
||||||
* fun main<CoinType>(user: &signer) {
|
* fun main<CoinType>(user: &signer) {
|
||||||
* if (!coin::is_account_registered<CoinType>(signer::address_of(user))) {
|
* if (!coin::is_account_registered<CoinType>(signer::address_of(user))) {
|
||||||
* coin::register<CoinType>(user);
|
* coin::register<CoinType>(user);
|
||||||
|
@ -170,7 +172,9 @@ export const registerCoin = (
|
||||||
// Deploy coin
|
// Deploy coin
|
||||||
|
|
||||||
// don't need `signer` and `&signer` in argument list because the Move VM will inject them
|
// 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.");
|
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
||||||
return {
|
return {
|
||||||
function: `${tokenBridgeAddress}::deploy_coin::deploy_coin`,
|
function: `${tokenBridgeAddress}::deploy_coin::deploy_coin`,
|
||||||
|
@ -183,7 +187,7 @@ export const deployCoin = (tokenBridgeAddress: string): Types.EntryFunctionPaylo
|
||||||
|
|
||||||
export const registerChain = (
|
export const registerChain = (
|
||||||
tokenBridgeAddress: string,
|
tokenBridgeAddress: string,
|
||||||
vaa: Uint8Array,
|
vaa: Uint8Array
|
||||||
): Types.EntryFunctionPayload => {
|
): Types.EntryFunctionPayload => {
|
||||||
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
if (!tokenBridgeAddress) throw new Error("Need token bridge address.");
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -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 } from "@terra-money/terra.js";
|
||||||
import { TxInfo as XplaTxInfo } from "@xpla/xpla.js";
|
import { TxInfo as XplaTxInfo } from "@xpla/xpla.js";
|
||||||
import { AptosClient, Types } from "aptos";
|
import { AptosClient, Types } from "aptos";
|
||||||
|
@ -105,7 +108,9 @@ export function parseSequenceFromLogInjective(info: any): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
const SOLANA_SEQ_LOG = "Program log: Sequence: ";
|
const SOLANA_SEQ_LOG = "Program log: Sequence: ";
|
||||||
export function parseSequenceFromLogSolana(info: TransactionResponse | VersionedTransactionResponse) {
|
export function parseSequenceFromLogSolana(
|
||||||
|
info: TransactionResponse | VersionedTransactionResponse
|
||||||
|
) {
|
||||||
// TODO: better parsing, safer
|
// TODO: better parsing, safer
|
||||||
const sequence = info.meta?.logMessages
|
const sequence = info.meta?.logMessages
|
||||||
?.filter((msg) => msg.startsWith(SOLANA_SEQ_LOG))?.[0]
|
?.filter((msg) => msg.startsWith(SOLANA_SEQ_LOG))?.[0]
|
||||||
|
|
|
@ -16,6 +16,6 @@ export * as token_bridge from "./token_bridge";
|
||||||
export * as nft_bridge from "./nft_bridge";
|
export * as nft_bridge from "./nft_bridge";
|
||||||
export * as algorand from "./algorand";
|
export * as algorand from "./algorand";
|
||||||
export * as sui from "./sui";
|
export * as sui from "./sui";
|
||||||
export * as relayer from "./relayer"
|
export * as relayer from "./relayer";
|
||||||
|
|
||||||
export { postVaaSolana, postVaaSolanaWithRetry } from "./solana";
|
export { postVaaSolana, postVaaSolanaWithRetry } from "./solana";
|
||||||
|
|
|
@ -265,6 +265,4 @@ export class GovernanceEmitter extends MockEmitter {
|
||||||
uptickSequence
|
uptickSequence
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 { ethers } from "ethers";
|
||||||
import { DeliveryProvider__factory } from "../../ethers-contracts"
|
import { DeliveryProvider__factory } from "../../ethers-contracts";
|
||||||
import {getAddressInfo} from "../consts"
|
import { getAddressInfo } from "../consts";
|
||||||
import {getDefaultProvider} from "../relayer/helpers"
|
import { getDefaultProvider } from "../relayer/helpers";
|
||||||
import {CHAINS, ChainId, ChainName, Network} from "../../../"
|
import { CHAINS, ChainId, ChainName, Network } from "../../../";
|
||||||
import {getNetwork, PRIVATE_KEY, isCI} from "./utils/utils";
|
import { getNetwork, PRIVATE_KEY, isCI } from "./utils/utils";
|
||||||
|
|
||||||
|
|
||||||
const network: Network = getNetwork();
|
const network: Network = getNetwork();
|
||||||
const ci: boolean = isCI();
|
const ci: boolean = isCI();
|
||||||
|
|
||||||
const sourceChain = network == 'DEVNET' ? "ethereum" : "avalanche";
|
const sourceChain = network == "DEVNET" ? "ethereum" : "avalanche";
|
||||||
const targetChain = network == 'DEVNET' ? "bsc" : "celo";
|
const targetChain = network == "DEVNET" ? "bsc" : "celo";
|
||||||
|
|
||||||
const sourceChainId = CHAINS[sourceChain];
|
const sourceChainId = CHAINS[sourceChain];
|
||||||
const targetChainId = CHAINS[targetChain];
|
const targetChainId = CHAINS[targetChain];
|
||||||
|
|
||||||
describe("Relay Provider Test", () => {
|
describe("Relay Provider Test", () => {
|
||||||
|
|
||||||
|
|
||||||
const addressInfo = getAddressInfo(sourceChain, network);
|
const addressInfo = getAddressInfo(sourceChain, network);
|
||||||
const provider = getDefaultProvider(network, sourceChain, ci);
|
const provider = getDefaultProvider(network, sourceChain, ci);
|
||||||
|
|
||||||
// signers
|
// signers
|
||||||
const oracleDeployer = new ethers.Wallet(PRIVATE_KEY, provider);
|
const oracleDeployer = new ethers.Wallet(PRIVATE_KEY, provider);
|
||||||
const deliveryProviderAddress = addressInfo.mockDeliveryProviderAddress;
|
const deliveryProviderAddress = addressInfo.mockDeliveryProviderAddress;
|
||||||
if(!deliveryProviderAddress) throw Error("No relay provider address");
|
if (!deliveryProviderAddress) throw Error("No relay provider address");
|
||||||
const deliveryProvider = DeliveryProvider__factory.connect(deliveryProviderAddress, oracleDeployer);
|
const deliveryProvider = DeliveryProvider__factory.connect(
|
||||||
|
deliveryProviderAddress,
|
||||||
|
oracleDeployer
|
||||||
|
);
|
||||||
|
|
||||||
describe("Read Prices Correctly", () => {
|
describe("Read Prices Correctly", () => {
|
||||||
test("readPrices", async () => {
|
test("readPrices", async () => {
|
||||||
const tokenPrice = ethers.BigNumber.from("100000");
|
const tokenPrice = ethers.BigNumber.from("100000");
|
||||||
const gasPrice = ethers.utils.parseUnits("300", "gwei");
|
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);
|
const gasPriceReturned = await deliveryProvider.gasPrice(targetChainId);
|
||||||
|
|
||||||
expect(tokenPriceReturned.toString()).toBe(tokenPrice.toString());
|
expect(tokenPriceReturned.toString()).toBe(tokenPrice.toString());
|
||||||
expect(gasPriceReturned.toString()).toBe(gasPrice.toString());
|
expect(gasPriceReturned.toString()).toBe(gasPrice.toString());
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,26 +1,32 @@
|
||||||
import { Network } from "../../../utils";
|
import { Network } from "../../../utils";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import { ethers } from "ethers";
|
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 SAFE_RELAY_DELAY = 10000;
|
||||||
|
|
||||||
const characters =
|
const characters =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
"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 networkOptions = ["MAINNET", "TESTNET", "DEVNET"];
|
||||||
|
|
||||||
export const isCI = (): boolean => {
|
export const isCI = (): boolean => {
|
||||||
return !!process.env['CI'];
|
return !!process.env["CI"];
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getNetwork = (): Network => {
|
export const getNetwork = (): Network => {
|
||||||
const network = process.env['NETWORK'] || "";
|
const network = process.env["NETWORK"] || "";
|
||||||
if(!(networkOptions.includes(network))) throw Error(`Invalid Network: ${network}. Options ${networkOptions.join(", ")}`);
|
if (!networkOptions.includes(network))
|
||||||
return network as Network;
|
throw Error(
|
||||||
}
|
`Invalid Network: ${network}. Options ${networkOptions.join(", ")}`
|
||||||
|
);
|
||||||
|
return network as Network;
|
||||||
|
};
|
||||||
|
|
||||||
export const generateRandomString = (length: number) => {
|
export const generateRandomString = (length: number) => {
|
||||||
let randomString = "";
|
let randomString = "";
|
||||||
|
@ -36,7 +42,7 @@ export const getArbitraryBytes32 = (): string => {
|
||||||
return ethers.utils.hexlify(
|
return ethers.utils.hexlify(
|
||||||
ethers.utils.toUtf8Bytes(generateRandomString(32))
|
ethers.utils.toUtf8Bytes(generateRandomString(32))
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function waitForRelay(quantity?: number) {
|
export async function waitForRelay(quantity?: number) {
|
||||||
await new Promise((resolve) =>
|
await new Promise((resolve) =>
|
||||||
|
@ -45,36 +51,48 @@ export async function waitForRelay(quantity?: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getGuardianRPC = (network: Network, ci: boolean) => {
|
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
|
// 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)
|
// Ideally we find a better home for these (probably somewhere in the SDK)
|
||||||
// These are used to mock a devnet/CI guardian
|
// These are used to mock a devnet/CI guardian
|
||||||
|
|
||||||
export const GUARDIAN_KEYS = process.env.GUARDIAN_KEY ? [process.env.GUARDIAN_KEY] : [
|
export const GUARDIAN_KEYS = process.env.GUARDIAN_KEY
|
||||||
"cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0",
|
? [process.env.GUARDIAN_KEY]
|
||||||
"c3b2e45c422a1602333a64078aeb42637370b0f48fe385f9cfa6ad54a8e0c47e",
|
: [
|
||||||
"9f790d3f08bc4b5cd910d4278f3deb406e57bb5e924906ccd52052bb078ccd47",
|
"cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0",
|
||||||
"b20cc49d6f2c82a5e6519015fc18aa3e562867f85f872c58f1277cfbd2a0c8e4",
|
"c3b2e45c422a1602333a64078aeb42637370b0f48fe385f9cfa6ad54a8e0c47e",
|
||||||
"eded5a2fdcb5bbbfa5b07f2a91393813420e7ac30a72fc935b6df36f8294b855",
|
"9f790d3f08bc4b5cd910d4278f3deb406e57bb5e924906ccd52052bb078ccd47",
|
||||||
"00d39587c3556f289677a837c7f3c0817cb7541ce6e38a243a4bdc761d534c5e",
|
"b20cc49d6f2c82a5e6519015fc18aa3e562867f85f872c58f1277cfbd2a0c8e4",
|
||||||
"da534d61a8da77b232f3a2cee55c0125e2b3e33a5cd8247f3fe9e72379445c3b",
|
"eded5a2fdcb5bbbfa5b07f2a91393813420e7ac30a72fc935b6df36f8294b855",
|
||||||
"cdbabfc2118eb00bc62c88845f3bbd03cb67a9e18a055101588ca9b36387006c",
|
"00d39587c3556f289677a837c7f3c0817cb7541ce6e38a243a4bdc761d534c5e",
|
||||||
"c83d36423820e7350428dc4abe645cb2904459b7d7128adefe16472fdac397ba",
|
"da534d61a8da77b232f3a2cee55c0125e2b3e33a5cd8247f3fe9e72379445c3b",
|
||||||
"1cbf4e1388b81c9020500fefc83a7a81f707091bb899074db1bfce4537428112",
|
"cdbabfc2118eb00bc62c88845f3bbd03cb67a9e18a055101588ca9b36387006c",
|
||||||
"17646a6ba14a541957fc7112cc973c0b3f04fce59484a92c09bb45a0b57eb740",
|
"c83d36423820e7350428dc4abe645cb2904459b7d7128adefe16472fdac397ba",
|
||||||
"eb94ff04accbfc8195d44b45e7c7da4c6993b2fbbfc4ef166a7675a905df9891",
|
"1cbf4e1388b81c9020500fefc83a7a81f707091bb899074db1bfce4537428112",
|
||||||
"053a6527124b309d914a47f5257a995e9b0ad17f14659f90ed42af5e6e262b6a",
|
"17646a6ba14a541957fc7112cc973c0b3f04fce59484a92c09bb45a0b57eb740",
|
||||||
"3fbf1e46f6da69e62aed5670f279e818889aa7d8f1beb7fd730770fd4f8ea3d7",
|
"eb94ff04accbfc8195d44b45e7c7da4c6993b2fbbfc4ef166a7675a905df9891",
|
||||||
"53b05697596ba04067e40be8100c9194cbae59c90e7870997de57337497172e9",
|
"053a6527124b309d914a47f5257a995e9b0ad17f14659f90ed42af5e6e262b6a",
|
||||||
"4e95cb2ff3f7d5e963631ad85c28b1b79cb370f21c67cbdd4c2ffb0bf664aa06",
|
"3fbf1e46f6da69e62aed5670f279e818889aa7d8f1beb7fd730770fd4f8ea3d7",
|
||||||
"01b8c448ce2c1d43cfc5938d3a57086f88e3dc43bb8b08028ecb7a7924f4676f",
|
"53b05697596ba04067e40be8100c9194cbae59c90e7870997de57337497172e9",
|
||||||
"1db31a6ba3bcd54d2e8a64f8a2415064265d291593450c6eb7e9a6a986bd9400",
|
"4e95cb2ff3f7d5e963631ad85c28b1b79cb370f21c67cbdd4c2ffb0bf664aa06",
|
||||||
"70d8f1c9534a0ab61a020366b831a494057a289441c07be67e4288c44bc6cd5d",
|
"01b8c448ce2c1d43cfc5938d3a57086f88e3dc43bb8b08028ecb7a7924f4676f",
|
||||||
];
|
"1db31a6ba3bcd54d2e8a64f8a2415064265d291593450c6eb7e9a6a986bd9400",
|
||||||
export const GUARDIAN_SET_INDEX = process.env.GUARDIAN_SET_INDEX ? parseInt(process.env.GUARDIAN_SET_INDEX) : 0;
|
"70d8f1c9534a0ab61a020366b831a494057a289441c07be67e4288c44bc6cd5d",
|
||||||
export const GOVERNANCE_EMITTER_ADDRESS = process.env.GOVERNANCE_EMITTER_ADDRESS || new PublicKey(
|
];
|
||||||
"11111111111111111111111111111115"
|
export const GUARDIAN_SET_INDEX = process.env.GUARDIAN_SET_INDEX
|
||||||
).toBuffer().toString("hex");
|
? parseInt(process.env.GUARDIAN_SET_INDEX)
|
||||||
|
: 0;
|
||||||
|
export const GOVERNANCE_EMITTER_ADDRESS =
|
||||||
|
process.env.GOVERNANCE_EMITTER_ADDRESS ||
|
||||||
|
new PublicKey("11111111111111111111111111111115").toBuffer().toString("hex");
|
||||||
|
|
|
@ -21,7 +21,7 @@ import {
|
||||||
VaaKey,
|
VaaKey,
|
||||||
DeliveryOverrideArgs,
|
DeliveryOverrideArgs,
|
||||||
parseForwardFailureError,
|
parseForwardFailureError,
|
||||||
parseRefundStatus
|
parseRefundStatus,
|
||||||
} from "../structs";
|
} from "../structs";
|
||||||
import {
|
import {
|
||||||
DeliveryProvider,
|
DeliveryProvider,
|
||||||
|
|
|
@ -19,7 +19,7 @@ export type SendOptionalParams = {
|
||||||
chainId?: ChainId;
|
chainId?: ChainId;
|
||||||
emitterAddress: string;
|
emitterAddress: string;
|
||||||
sequenceNumber: ethers.BigNumberish;
|
sequenceNumber: ethers.BigNumberish;
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
deliveryProviderAddress?: string;
|
deliveryProviderAddress?: string;
|
||||||
wormholeRelayerAddress?: string;
|
wormholeRelayerAddress?: string;
|
||||||
|
|
|
@ -7,7 +7,7 @@ export enum RelayerPayloadId {
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ExecutionInfoVersion {
|
export enum ExecutionInfoVersion {
|
||||||
EVM_V1 = 0
|
EVM_V1 = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum DeliveryStatus {
|
export enum DeliveryStatus {
|
||||||
|
@ -26,16 +26,21 @@ export enum RefundStatus {
|
||||||
RefundFail = "Refund Fail",
|
RefundFail = "Refund Fail",
|
||||||
CrossChainRefundSent = "Cross Chain Refund Sent",
|
CrossChainRefundSent = "Cross Chain Refund Sent",
|
||||||
CrossChainRefundFailProviderNotSupported = "Cross Chain Refund Fail - Provider does not support the refund chain",
|
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) {
|
export function parseRefundStatus(index: number) {
|
||||||
return index === 0 ? RefundStatus.RefundSent
|
return index === 0
|
||||||
: index === 1 ? RefundStatus.RefundFail
|
? RefundStatus.RefundSent
|
||||||
: index === 2 ? RefundStatus.CrossChainRefundSent
|
: index === 1
|
||||||
: index === 3 ? RefundStatus.CrossChainRefundFailProviderNotSupported
|
? RefundStatus.RefundFail
|
||||||
: index === 4 ? RefundStatus.CrossChainRefundFailNotEnough
|
: index === 2
|
||||||
: RefundStatus.CrossChainRefundFailProviderNotSupported;
|
? RefundStatus.CrossChainRefundSent
|
||||||
|
: index === 3
|
||||||
|
? RefundStatus.CrossChainRefundFailProviderNotSupported
|
||||||
|
: index === 4
|
||||||
|
? RefundStatus.CrossChainRefundFailNotEnough
|
||||||
|
: RefundStatus.CrossChainRefundFailProviderNotSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VaaKey {
|
export interface VaaKey {
|
||||||
|
@ -184,7 +189,7 @@ export function parseWormholeRelayerSend(bytes: Buffer): DeliveryInstruction {
|
||||||
refundDeliveryProvider,
|
refundDeliveryProvider,
|
||||||
sourceDeliveryProvider,
|
sourceDeliveryProvider,
|
||||||
senderAddress,
|
senderAddress,
|
||||||
vaaKeys: messages
|
vaaKeys: messages,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,23 +205,22 @@ function parseVaaKey(bytes: Buffer, idx: number): [VaaKey, number] {
|
||||||
const version = bytes.readUInt8(idx);
|
const version = bytes.readUInt8(idx);
|
||||||
idx += 1;
|
idx += 1;
|
||||||
|
|
||||||
const chainId = bytes.readUInt16BE(idx);
|
const chainId = bytes.readUInt16BE(idx);
|
||||||
idx += 2;
|
idx += 2;
|
||||||
const emitterAddress = bytes.slice(idx, idx + 32);
|
const emitterAddress = bytes.slice(idx, idx + 32);
|
||||||
idx += 32;
|
idx += 32;
|
||||||
const sequence = ethers.BigNumber.from(
|
const sequence = ethers.BigNumber.from(
|
||||||
Uint8Array.prototype.subarray.call(bytes, idx, idx + 8)
|
Uint8Array.prototype.subarray.call(bytes, idx, idx + 8)
|
||||||
);
|
);
|
||||||
idx += 8;
|
idx += 8;
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
chainId,
|
chainId,
|
||||||
emitterAddress,
|
emitterAddress,
|
||||||
sequence,
|
sequence,
|
||||||
},
|
},
|
||||||
idx,
|
idx,
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseEVMExecutionInfoV1(
|
export function parseEVMExecutionInfoV1(
|
||||||
|
@ -226,7 +230,7 @@ export function parseEVMExecutionInfoV1(
|
||||||
idx += 31;
|
idx += 31;
|
||||||
const version = bytes.readUInt8(idx);
|
const version = bytes.readUInt8(idx);
|
||||||
idx += 1;
|
idx += 1;
|
||||||
if(version !== ExecutionInfoVersion.EVM_V1) {
|
if (version !== ExecutionInfoVersion.EVM_V1) {
|
||||||
throw new Error("Unexpected Execution Info version");
|
throw new Error("Unexpected Execution Info version");
|
||||||
}
|
}
|
||||||
const gasLimit = ethers.BigNumber.from(
|
const gasLimit = ethers.BigNumber.from(
|
||||||
|
@ -267,11 +271,9 @@ export function parseWormholeRelayerResend(
|
||||||
let newEncodedExecutionInfo;
|
let newEncodedExecutionInfo;
|
||||||
[newEncodedExecutionInfo, idx] = parsePayload(bytes, idx);
|
[newEncodedExecutionInfo, idx] = parsePayload(bytes, idx);
|
||||||
|
|
||||||
|
|
||||||
const newSourceDeliveryProvider = bytes.slice(idx, idx + 32);
|
const newSourceDeliveryProvider = bytes.slice(idx, idx + 32);
|
||||||
idx += 32;
|
idx += 32;
|
||||||
|
|
||||||
|
|
||||||
const newSenderAddress = bytes.slice(idx, idx + 32);
|
const newSenderAddress = bytes.slice(idx, idx + 32);
|
||||||
idx += 32;
|
idx += 32;
|
||||||
return {
|
return {
|
||||||
|
@ -280,14 +282,12 @@ export function parseWormholeRelayerResend(
|
||||||
newRequestedReceiverValue,
|
newRequestedReceiverValue,
|
||||||
newEncodedExecutionInfo,
|
newEncodedExecutionInfo,
|
||||||
newSourceDeliveryProvider,
|
newSourceDeliveryProvider,
|
||||||
newSenderAddress
|
newSenderAddress,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function executionInfoToString(
|
export function executionInfoToString(encodedExecutionInfo: Buffer): string {
|
||||||
encodedExecutionInfo: Buffer
|
const [parsed] = parseEVMExecutionInfoV1(encodedExecutionInfo, 0);
|
||||||
): string {
|
|
||||||
const [parsed,] = parseEVMExecutionInfoV1(encodedExecutionInfo, 0)
|
|
||||||
return `Gas limit: ${parsed.gasLimit}, Target chain refund per unit gas unused: ${parsed.targetChainRefundPerGasUnused}`;
|
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<VaaKey> {
|
export function vaaKeyPrintable(ix: VaaKey): StringLeaves<VaaKey> {
|
||||||
return {
|
return {
|
||||||
chainId: ix.chainId?.toString(),
|
chainId: ix.chainId?.toString(),
|
||||||
emitterAddress: ix.emitterAddress?.toString("hex"),
|
emitterAddress: ix.emitterAddress?.toString("hex"),
|
||||||
sequence: ix.sequence?.toString(),
|
sequence: ix.sequence?.toString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function redeliveryInstructionPrintable(
|
export function redeliveryInstructionPrintable(
|
||||||
|
@ -327,7 +327,7 @@ export function redeliveryInstructionPrintable(
|
||||||
newRequestedReceiverValue: ix.newRequestedReceiverValue.toString(),
|
newRequestedReceiverValue: ix.newRequestedReceiverValue.toString(),
|
||||||
newEncodedExecutionInfo: executionInfoToString(ix.newEncodedExecutionInfo),
|
newEncodedExecutionInfo: executionInfoToString(ix.newEncodedExecutionInfo),
|
||||||
newSourceDeliveryProvider: ix.newSourceDeliveryProvider.toString("hex"),
|
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;
|
return "0x" + packed;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseForwardFailureError(
|
export function parseForwardFailureError(bytes: Buffer): string {
|
||||||
bytes: Buffer
|
|
||||||
): string {
|
|
||||||
let idx = 4;
|
let idx = 4;
|
||||||
idx += 32;
|
idx += 32;
|
||||||
if(bytes.length <= idx) {
|
if (bytes.length <= idx) {
|
||||||
return `Delivery Provider failed in performing forward`
|
return `Delivery Provider failed in performing forward`;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const amountOfFunds = ethers.BigNumber.from(
|
const amountOfFunds = ethers.BigNumber.from(
|
||||||
|
@ -369,12 +367,12 @@ export function parseForwardFailureError(
|
||||||
const amountOfFundsNeeded = ethers.BigNumber.from(
|
const amountOfFundsNeeded = ethers.BigNumber.from(
|
||||||
Uint8Array.prototype.subarray.call(bytes, idx, idx + 32)
|
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) {
|
} catch (err) {
|
||||||
return `Delivery Provider unexpectedly failed in performing forward`
|
return `Delivery Provider unexpectedly failed in performing forward`;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseOverrideInfoFromDeliveryEvent(
|
export function parseOverrideInfoFromDeliveryEvent(
|
||||||
|
@ -397,7 +395,7 @@ export function parseOverrideInfoFromDeliveryEvent(
|
||||||
return {
|
return {
|
||||||
newReceiverValue,
|
newReceiverValue,
|
||||||
newExecutionInfo,
|
newExecutionInfo,
|
||||||
redeliveryHash
|
redeliveryHash,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,9 @@ import { IdlEvent } from "../../anchor";
|
||||||
export class WormholeEventsCoder implements EventCoder {
|
export class WormholeEventsCoder implements EventCoder {
|
||||||
constructor(_idl: Idl) {}
|
constructor(_idl: Idl) {}
|
||||||
|
|
||||||
decode<E extends IdlEvent = IdlEvent, T = Record<string, string>>(_log: string): Event<E, T> | null {
|
decode<E extends IdlEvent = IdlEvent, T = Record<string, string>>(
|
||||||
|
_log: string
|
||||||
|
): Event<E, T> | null {
|
||||||
throw new Error("Wormhole program does not have events");
|
throw new Error("Wormhole program does not have events");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,111 +2,111 @@
|
||||||
//
|
//
|
||||||
// https://github.com/coral-xyz/anchor/blob/master/ts/packages/anchor/src/coder/borsh/idl.ts
|
// 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 { Layout } from "buffer-layout";
|
||||||
import { IdlField, IdlTypeDef } from "../../anchor";
|
import { IdlField, IdlTypeDef } from "../../anchor";
|
||||||
import { camelCase } from "lodash";
|
import { camelCase } from "lodash";
|
||||||
|
|
||||||
export class IdlCoder {
|
export class IdlCoder {
|
||||||
public static fieldLayout(
|
public static fieldLayout(
|
||||||
field: { name?: string } & Pick<IdlField, "type">,
|
field: { name?: string } & Pick<IdlField, "type">,
|
||||||
types?: IdlTypeDef[]
|
types?: IdlTypeDef[]
|
||||||
): Layout {
|
): Layout {
|
||||||
const fieldName =
|
const fieldName =
|
||||||
field.name !== undefined ? camelCase(field.name) : undefined;
|
field.name !== undefined ? camelCase(field.name) : undefined;
|
||||||
switch (field.type) {
|
switch (field.type) {
|
||||||
case "bool": {
|
case "bool": {
|
||||||
return borsh.bool(fieldName);
|
return borsh.bool(fieldName);
|
||||||
}
|
}
|
||||||
case "u8": {
|
case "u8": {
|
||||||
return borsh.u8(fieldName);
|
return borsh.u8(fieldName);
|
||||||
}
|
}
|
||||||
case "i8": {
|
case "i8": {
|
||||||
return borsh.i8(fieldName);
|
return borsh.i8(fieldName);
|
||||||
}
|
}
|
||||||
case "u16": {
|
case "u16": {
|
||||||
return borsh.u16(fieldName);
|
return borsh.u16(fieldName);
|
||||||
}
|
}
|
||||||
case "i16": {
|
case "i16": {
|
||||||
return borsh.i16(fieldName);
|
return borsh.i16(fieldName);
|
||||||
}
|
}
|
||||||
case "u32": {
|
case "u32": {
|
||||||
return borsh.u32(fieldName);
|
return borsh.u32(fieldName);
|
||||||
}
|
}
|
||||||
case "i32": {
|
case "i32": {
|
||||||
return borsh.i32(fieldName);
|
return borsh.i32(fieldName);
|
||||||
}
|
}
|
||||||
case "f32": {
|
case "f32": {
|
||||||
return borsh.f32(fieldName);
|
return borsh.f32(fieldName);
|
||||||
}
|
}
|
||||||
case "u64": {
|
case "u64": {
|
||||||
return borsh.u64(fieldName);
|
return borsh.u64(fieldName);
|
||||||
}
|
}
|
||||||
case "i64": {
|
case "i64": {
|
||||||
return borsh.i64(fieldName);
|
return borsh.i64(fieldName);
|
||||||
}
|
}
|
||||||
case "f64": {
|
case "f64": {
|
||||||
return borsh.f64(fieldName);
|
return borsh.f64(fieldName);
|
||||||
}
|
}
|
||||||
case "u128": {
|
case "u128": {
|
||||||
return borsh.u128(fieldName);
|
return borsh.u128(fieldName);
|
||||||
}
|
}
|
||||||
case "i128": {
|
case "i128": {
|
||||||
return borsh.i128(fieldName);
|
return borsh.i128(fieldName);
|
||||||
}
|
}
|
||||||
case "u256": {
|
case "u256": {
|
||||||
return borsh.u256(fieldName);
|
return borsh.u256(fieldName);
|
||||||
}
|
}
|
||||||
case "i256": {
|
case "i256": {
|
||||||
return borsh.i256(fieldName);
|
return borsh.i256(fieldName);
|
||||||
}
|
}
|
||||||
case "bytes": {
|
case "bytes": {
|
||||||
return borsh.vecU8(fieldName);
|
return borsh.vecU8(fieldName);
|
||||||
}
|
}
|
||||||
case "string": {
|
case "string": {
|
||||||
return borsh.str(fieldName);
|
return borsh.str(fieldName);
|
||||||
}
|
}
|
||||||
case "publicKey": {
|
case "publicKey": {
|
||||||
return borsh.publicKey(fieldName);
|
return borsh.publicKey(fieldName);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
if ("vec" in field.type) {
|
if ("vec" in field.type) {
|
||||||
return borsh.vec(
|
return borsh.vec(
|
||||||
IdlCoder.fieldLayout(
|
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(
|
|
||||||
{
|
{
|
||||||
name: undefined,
|
name: undefined,
|
||||||
type: arrayTy,
|
type: field.type.vec,
|
||||||
},
|
},
|
||||||
types
|
types
|
||||||
);
|
),
|
||||||
return borsh.array(innerLayout, arrayLen, fieldName);
|
fieldName
|
||||||
} else {
|
);
|
||||||
throw new Error(`Not yet implemented: ${field}`);
|
} 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}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,4 +9,4 @@ export class WormholeStateCoder implements StateCoder {
|
||||||
decode<T = any>(_ix: Buffer): T {
|
decode<T = any>(_ix: Buffer): T {
|
||||||
throw new Error("Wormhole program does not have state");
|
throw new Error("Wormhole program does not have state");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { Idl, TypesCoder } from "@project-serum/anchor";
|
import { Idl, TypesCoder } from "@project-serum/anchor";
|
||||||
|
|
||||||
export class WormholeTypesCoder implements TypesCoder {
|
export class WormholeTypesCoder implements TypesCoder {
|
||||||
constructor(_idl: Idl) {}
|
constructor(_idl: Idl) {}
|
||||||
|
|
||||||
encode<T = any>(_name: string, _type: T): Buffer {
|
encode<T = any>(_name: string, _type: T): Buffer {
|
||||||
throw new Error("Wormhole program does not have user-defined types");
|
throw new Error("Wormhole program does not have user-defined types");
|
||||||
}
|
}
|
||||||
decode<T = any>(_name: string, _typeData: Buffer): T {
|
decode<T = any>(_name: string, _typeData: Buffer): T {
|
||||||
throw new Error("Wormhole program does not have user-defined types");
|
throw new Error("Wormhole program does not have user-defined types");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,9 @@ export function createInitializeInstruction(
|
||||||
): TransactionInstruction {
|
): TransactionInstruction {
|
||||||
const methods = createReadOnlyWormholeProgramInterface(
|
const methods = createReadOnlyWormholeProgramInterface(
|
||||||
wormholeProgramId
|
wormholeProgramId
|
||||||
).methods.initialize(
|
).methods.initialize(guardianSetExpirationTime, new BN(fee.toString()), [
|
||||||
guardianSetExpirationTime,
|
...initialGuardians,
|
||||||
new BN(fee.toString()),
|
]);
|
||||||
[...initialGuardians]
|
|
||||||
);
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return methods._ixFn(...methods._args, {
|
return methods._ixFn(...methods._args, {
|
||||||
|
|
|
@ -70,7 +70,7 @@ export async function createVerifySignaturesInstructions(
|
||||||
for (let i = 0; i < Math.ceil(guardianSignatures.length / batchSize); ++i) {
|
for (let i = 0; i < Math.ceil(guardianSignatures.length / batchSize); ++i) {
|
||||||
const start = i * batchSize;
|
const start = i * batchSize;
|
||||||
const end = Math.min(guardianSignatures.length, (i + 1) * batchSize);
|
const end = Math.min(guardianSignatures.length, (i + 1) * batchSize);
|
||||||
|
|
||||||
const signatureStatus = new Array(MAX_LEN_GUARDIAN_KEYS).fill(-1);
|
const signatureStatus = new Array(MAX_LEN_GUARDIAN_KEYS).fill(-1);
|
||||||
const signatures: Buffer[] = [];
|
const signatures: Buffer[] = [];
|
||||||
const keys: Buffer[] = [];
|
const keys: Buffer[] = [];
|
||||||
|
@ -123,9 +123,10 @@ function createVerifySignaturesInstruction(
|
||||||
signatureSet: PublicKeyInitData,
|
signatureSet: PublicKeyInitData,
|
||||||
signatureStatus: number[]
|
signatureStatus: number[]
|
||||||
): TransactionInstruction {
|
): TransactionInstruction {
|
||||||
const methods = createReadOnlyWormholeProgramInterface(
|
const methods =
|
||||||
wormholeProgramId
|
createReadOnlyWormholeProgramInterface(
|
||||||
).methods.verifySignatures(signatureStatus);
|
wormholeProgramId
|
||||||
|
).methods.verifySignatures(signatureStatus);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return methods._ixFn(...methods._args, {
|
return methods._ixFn(...methods._args, {
|
||||||
|
|
|
@ -109,7 +109,7 @@ export const tryUint8ArrayToNative = (
|
||||||
} else if (chainId === CHAIN_ID_XPLA) {
|
} else if (chainId === CHAIN_ID_XPLA) {
|
||||||
return humanAddress("xpla", a.slice(-20));
|
return humanAddress("xpla", a.slice(-20));
|
||||||
} else if (chainId === CHAIN_ID_SEI) {
|
} else if (chainId === CHAIN_ID_SEI) {
|
||||||
return humanAddress("sei", a.slice(-20));
|
return humanAddress("sei", a.slice(-20));
|
||||||
} else if (chainId === CHAIN_ID_NEAR) {
|
} else if (chainId === CHAIN_ID_NEAR) {
|
||||||
throw Error("uint8ArrayToNative: Use tryHexToNativeStringNear instead.");
|
throw Error("uint8ArrayToNative: Use tryHexToNativeStringNear instead.");
|
||||||
} else if (chainId === CHAIN_ID_OSMOSIS) {
|
} else if (chainId === CHAIN_ID_OSMOSIS) {
|
||||||
|
|
|
@ -63,12 +63,14 @@ export const EVMChainNames: ReadonlyArray<ChainName> = [
|
||||||
] as const;
|
] as const;
|
||||||
export type EVMChainName = (typeof EVMChainNames)[number];
|
export type EVMChainName = (typeof EVMChainNames)[number];
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* All the Solana-based chain names that Wormhole supports
|
* All the Solana-based chain names that Wormhole supports
|
||||||
*/
|
*/
|
||||||
export const SolanaChainNames: ReadonlyArray<ChainName> = ["solana", "pythnet"] as const;
|
export const SolanaChainNames: ReadonlyArray<ChainName> = [
|
||||||
|
"solana",
|
||||||
|
"pythnet",
|
||||||
|
] as const;
|
||||||
export type SolanaChainName = (typeof SolanaChainNames)[number];
|
export type SolanaChainName = (typeof SolanaChainNames)[number];
|
||||||
|
|
||||||
export const CosmWasmChainNames: ReadonlyArray<ChainName> = [
|
export const CosmWasmChainNames: ReadonlyArray<ChainName> = [
|
||||||
|
@ -81,7 +83,10 @@ export const CosmWasmChainNames: ReadonlyArray<ChainName> = [
|
||||||
export type CosmWasmChainName = (typeof CosmWasmChainNames)[number];
|
export type CosmWasmChainName = (typeof CosmWasmChainNames)[number];
|
||||||
|
|
||||||
// TODO: why? these are dupe of entries in CosmWasm
|
// TODO: why? these are dupe of entries in CosmWasm
|
||||||
export const TerraChainNames: ReadonlyArray<ChainName> = ["terra", "terra2"] as const;
|
export const TerraChainNames: ReadonlyArray<ChainName> = [
|
||||||
|
"terra",
|
||||||
|
"terra2",
|
||||||
|
] as const;
|
||||||
export type TerraChainName = (typeof TerraChainNames)[number];
|
export type TerraChainName = (typeof TerraChainNames)[number];
|
||||||
|
|
||||||
export type Contracts = {
|
export type Contracts = {
|
||||||
|
@ -810,7 +815,7 @@ export function isEVMChain(
|
||||||
chain: ChainId | ChainName
|
chain: ChainId | ChainName
|
||||||
): chain is EVMChainId | EVMChainName {
|
): chain is EVMChainId | EVMChainName {
|
||||||
const chainName = coalesceChainName(chain);
|
const chainName = coalesceChainName(chain);
|
||||||
return EVMChainNames.includes(chainName)
|
return EVMChainNames.includes(chainName);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isCosmWasmChain(
|
export function isCosmWasmChain(
|
||||||
|
|
|
@ -384,7 +384,7 @@ function serialiseCoreContractUpgrade(payload: CoreContractUpgrade): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PortalContractUpgrade<
|
export interface PortalContractUpgrade<
|
||||||
Module extends "NFTBridge" | "TokenBridge"
|
Module extends "NFTBridge" | "TokenBridge",
|
||||||
> {
|
> {
|
||||||
module: Module;
|
module: Module;
|
||||||
type: "ContractUpgrade";
|
type: "ContractUpgrade";
|
||||||
|
@ -394,7 +394,7 @@ export interface PortalContractUpgrade<
|
||||||
|
|
||||||
// Parse a portal contract upgrade payload
|
// Parse a portal contract upgrade payload
|
||||||
function portalContractUpgradeParser<
|
function portalContractUpgradeParser<
|
||||||
Module extends "NFTBridge" | "TokenBridge"
|
Module extends "NFTBridge" | "TokenBridge",
|
||||||
>(module: Module): P<PortalContractUpgrade<Module>> {
|
>(module: Module): P<PortalContractUpgrade<Module>> {
|
||||||
return new P(
|
return new P(
|
||||||
new Parser()
|
new Parser()
|
||||||
|
@ -423,7 +423,7 @@ function portalContractUpgradeParser<
|
||||||
}
|
}
|
||||||
|
|
||||||
function serialisePortalContractUpgrade<
|
function serialisePortalContractUpgrade<
|
||||||
Module extends "NFTBridge" | "TokenBridge"
|
Module extends "NFTBridge" | "TokenBridge",
|
||||||
>(payload: PortalContractUpgrade<Module>): string {
|
>(payload: PortalContractUpgrade<Module>): string {
|
||||||
const body = [
|
const body = [
|
||||||
encode("bytes32", encodeString(payload.module)),
|
encode("bytes32", encodeString(payload.module)),
|
||||||
|
@ -438,7 +438,7 @@ function serialisePortalContractUpgrade<
|
||||||
// Registrations
|
// Registrations
|
||||||
|
|
||||||
export interface PortalRegisterChain<
|
export interface PortalRegisterChain<
|
||||||
Module extends "NFTBridge" | "TokenBridge"
|
Module extends "NFTBridge" | "TokenBridge",
|
||||||
> {
|
> {
|
||||||
module: Module;
|
module: Module;
|
||||||
type: "RegisterChain";
|
type: "RegisterChain";
|
||||||
|
@ -479,7 +479,7 @@ function portalRegisterChainParser<Module extends "NFTBridge" | "TokenBridge">(
|
||||||
}
|
}
|
||||||
|
|
||||||
function serialisePortalRegisterChain<
|
function serialisePortalRegisterChain<
|
||||||
Module extends "NFTBridge" | "TokenBridge"
|
Module extends "NFTBridge" | "TokenBridge",
|
||||||
>(payload: PortalRegisterChain<Module>): string {
|
>(payload: PortalRegisterChain<Module>): string {
|
||||||
const body = [
|
const body = [
|
||||||
encode("bytes32", encodeString(payload.module)),
|
encode("bytes32", encodeString(payload.module)),
|
||||||
|
|
Loading…
Reference in New Issue