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
|
||||
- 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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
sdk/js/src/ethers-contracts
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -311,14 +311,14 @@ export const isSameType = (a: string, b: string) => {
|
|||
|
||||
export const isSuiCreateEvent = <
|
||||
T extends NonNullable<SuiTransactionBlockResponse["objectChanges"]>[number],
|
||||
K extends Extract<T, { type: "created" }>
|
||||
K extends Extract<T, { type: "created" }>,
|
||||
>(
|
||||
event: T
|
||||
): event is K => event?.type === "created";
|
||||
|
||||
export const isSuiPublishEvent = <
|
||||
T extends NonNullable<SuiTransactionBlockResponse["objectChanges"]>[number],
|
||||
K extends Extract<T, { type: "published" }>
|
||||
K extends Extract<T, { type: "published" }>,
|
||||
>(
|
||||
event: T
|
||||
): event is K => event?.type === "published";
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 <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) =>
|
||||
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<ChainName, ethers.providers.Provider>();
|
||||
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));
|
||||
};
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
@ -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 = "<!--CLI_USAGE-->";
|
||||
|
||||
async function getHelpText(cmd: any): Promise<string> {
|
||||
// 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<string> {
|
|||
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(`
|
||||
<details>
|
||||
<summary> ${cmd.command} </summary>
|
||||
|
||||
|
@ -56,11 +56,10 @@ async function getHelpText(cmd: any): Promise<string> {
|
|||
${helpText}
|
||||
\`\`\`
|
||||
</details>
|
||||
`))
|
||||
`)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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());
|
||||
})();
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
getEmitterAddressEth,
|
||||
getEmitterAddressNear,
|
||||
getEmitterAddressSolana,
|
||||
getEmitterAddressTerra
|
||||
getEmitterAddressTerra,
|
||||
} from "@certusone/wormhole-sdk/lib/esm/bridge/getEmitterAddress";
|
||||
|
||||
export async function getEmitterAddress(
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
],
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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<Types.EntryFunctionPayload> => {
|
||||
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<Types.EntryFunctionPayload> => {
|
||||
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<CoinType>(user: &signer) {
|
||||
* if (!coin::is_account_registered<CoinType>(signer::address_of(user))) {
|
||||
* coin::register<CoinType>(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 {
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -265,6 +265,4 @@ export class GovernanceEmitter extends MockEmitter {
|
|||
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 { 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());
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
VaaKey,
|
||||
DeliveryOverrideArgs,
|
||||
parseForwardFailureError,
|
||||
parseRefundStatus
|
||||
parseRefundStatus,
|
||||
} from "../structs";
|
||||
import {
|
||||
DeliveryProvider,
|
||||
|
|
|
@ -19,7 +19,7 @@ export type SendOptionalParams = {
|
|||
chainId?: ChainId;
|
||||
emitterAddress: string;
|
||||
sequenceNumber: ethers.BigNumberish;
|
||||
}
|
||||
},
|
||||
];
|
||||
deliveryProviderAddress?: string;
|
||||
wormholeRelayerAddress?: string;
|
||||
|
|
|
@ -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<VaaKey> {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@ import { IdlEvent } from "../../anchor";
|
|||
export class WormholeEventsCoder implements EventCoder {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<IdlField, "type">,
|
||||
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<IdlField, "type">,
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,4 +9,4 @@ export class WormholeStateCoder implements StateCoder {
|
|||
decode<T = any>(_ix: Buffer): T {
|
||||
throw new Error("Wormhole program does not have state");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { Idl, TypesCoder } from "@project-serum/anchor";
|
||||
|
||||
export class WormholeTypesCoder implements TypesCoder {
|
||||
constructor(_idl: Idl) {}
|
||||
|
||||
encode<T = any>(_name: string, _type: T): Buffer {
|
||||
throw new Error("Wormhole program does not have user-defined types");
|
||||
}
|
||||
decode<T = any>(_name: string, _typeData: Buffer): T {
|
||||
throw new Error("Wormhole program does not have user-defined types");
|
||||
}
|
||||
}
|
||||
constructor(_idl: Idl) {}
|
||||
|
||||
encode<T = any>(_name: string, _type: T): Buffer {
|
||||
throw new Error("Wormhole program does not have user-defined types");
|
||||
}
|
||||
decode<T = any>(_name: string, _typeData: Buffer): T {
|
||||
throw new Error("Wormhole program does not have user-defined types");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, {
|
||||
|
|
|
@ -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, {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -63,12 +63,14 @@ export const EVMChainNames: ReadonlyArray<ChainName> = [
|
|||
] as const;
|
||||
export type EVMChainName = (typeof EVMChainNames)[number];
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 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 const CosmWasmChainNames: ReadonlyArray<ChainName> = [
|
||||
|
@ -81,7 +83,10 @@ export const CosmWasmChainNames: ReadonlyArray<ChainName> = [
|
|||
export type CosmWasmChainName = (typeof CosmWasmChainNames)[number];
|
||||
|
||||
// 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 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(
|
||||
|
|
|
@ -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<PortalContractUpgrade<Module>> {
|
||||
return new P(
|
||||
new Parser()
|
||||
|
@ -423,7 +423,7 @@ function portalContractUpgradeParser<
|
|||
}
|
||||
|
||||
function serialisePortalContractUpgrade<
|
||||
Module extends "NFTBridge" | "TokenBridge"
|
||||
Module extends "NFTBridge" | "TokenBridge",
|
||||
>(payload: PortalContractUpgrade<Module>): 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<Module extends "NFTBridge" | "TokenBridge">(
|
|||
}
|
||||
|
||||
function serialisePortalRegisterChain<
|
||||
Module extends "NFTBridge" | "TokenBridge"
|
||||
Module extends "NFTBridge" | "TokenBridge",
|
||||
>(payload: PortalRegisterChain<Module>): string {
|
||||
const body = [
|
||||
encode("bytes32", encodeString(payload.module)),
|
||||
|
|
Loading…
Reference in New Issue