From 0c933de70dc03d94b618095aaf9b5f1fa872a7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix?= Date: Wed, 15 Jan 2025 21:54:09 +0100 Subject: [PATCH] First step cleanup --- core/base/src/utils/misc.ts | 9 - package-lock.json | 8 +- package.json | 2 +- platforms/solana/protocols/core/package.json | 1 - .../core/src/accountLayout.ts} | 15 +- platforms/solana/protocols/core/src/core.ts | 75 ++- platforms/solana/protocols/core/src/index.ts | 3 +- .../protocols/core/src/postMessageLayout.ts | 27 - platforms/solana/protocols/core/src/types.ts | 122 ++++- .../core/src/utils/accounts/claim.ts | 54 -- .../core/src/utils/accounts/config.ts | 68 --- .../core/src/utils/accounts/emitter.ts | 45 -- .../core/src/utils/accounts/feeCollector.ts | 8 - .../core/src/utils/accounts/guardianSet.ts | 70 --- .../core/src/utils/accounts/index.ts | 9 - .../core/src/utils/accounts/postedVaa.ts | 12 - .../core/src/utils/accounts/sequence.ts | 63 --- .../core/src/utils/accounts/signatureSet.ts | 40 -- .../core/src/utils/accounts/upgrade.ts | 8 - .../core/src/utils/coder/accounts.ts | 78 --- .../protocols/core/src/utils/coder/events.ts | 13 - .../protocols/core/src/utils/coder/idl.ts | 112 ---- .../protocols/core/src/utils/coder/index.ts | 24 - .../core/src/utils/coder/instruction.ts | 117 ----- .../protocols/core/src/utils/coder/state.ts | 12 - .../protocols/core/src/utils/coder/types.ts | 12 - .../solana/protocols/core/src/utils/cpi.ts | 96 ---- .../solana/protocols/core/src/utils/index.ts | 4 - .../src/utils/instructions/feeTransfer.ts | 18 - .../core/src/utils/instructions/governance.ts | 258 ---------- .../core/src/utils/instructions/index.ts | 6 - .../core/src/utils/instructions/initialize.ts | 68 --- .../src/utils/instructions/postMessage.ts | 81 --- .../core/src/utils/instructions/postVaa.ts | 95 ---- .../core/src/utils/instructions/secp256k1.ts | 124 ----- .../src/utils/instructions/verifySignature.ts | 161 ------ .../protocols/core/src/utils/program.ts | 33 -- .../tokenBridge/src/automaticTokenBridge.ts | 39 +- .../src/automaticTokenBridgeType.ts | 116 +++-- .../solana/protocols/tokenBridge/src/index.ts | 1 - .../protocols/tokenBridge/src/tokenBridge.ts | 99 ++-- .../tokenBridge/src/tokenBridgeType.ts | 50 +- .../accounts/foreignContract.ts | 23 - .../automaticTokenBridge/accounts/index.ts | 6 - .../accounts/redeemerConfig.ts | 15 - .../accounts/registeredToken.ts | 19 - .../accounts/senderConfig.ts | 16 - .../accounts/signerSequence.ts | 18 - .../accounts/tmpTokenAccount.ts | 13 - .../accounts/tokenTransferMessage.ts | 20 - .../src/utils/automaticTokenBridge/index.ts | 3 - .../instructions/index.ts | 2 - .../transferNativeTokensWithRelay.ts | 85 --- .../transferWrappedTokensWithRelay.ts | 95 ---- .../src/utils/automaticTokenBridge/program.ts | 14 - .../protocols/tokenBridge/src/utils/index.ts | 3 - .../tokenBridge/src/utils/splMetadata.ts | 324 ------------ .../src/utils/tokenBridge/accounts/config.ts | 42 -- .../src/utils/tokenBridge/accounts/custody.ts | 13 - .../utils/tokenBridge/accounts/endpoint.ts | 68 --- .../src/utils/tokenBridge/accounts/index.ts | 6 - .../src/utils/tokenBridge/accounts/signer.ts | 29 -- .../accounts/transferWithPayload.ts | 14 - .../src/utils/tokenBridge/accounts/wrapped.ts | 94 ---- .../src/utils/tokenBridge/coder/accounts.ts | 40 -- .../src/utils/tokenBridge/coder/events.ts | 13 - .../src/utils/tokenBridge/coder/index.ts | 24 - .../utils/tokenBridge/coder/instruction.ts | 254 --------- .../src/utils/tokenBridge/coder/state.ts | 12 - .../src/utils/tokenBridge/coder/types.ts | 12 - .../tokenBridge/src/utils/tokenBridge/cpi.ts | 485 ------------------ .../src/utils/tokenBridge/index.ts | 4 - .../utils/tokenBridge/instructions/approve.ts | 18 - .../tokenBridge/instructions/attestToken.ts | 108 ---- .../instructions/completeNative.ts | 102 ---- .../instructions/completeWrapped.ts | 107 ---- .../tokenBridge/instructions/createWrapped.ts | 104 ---- .../tokenBridge/instructions/governance.ts | 154 ------ .../utils/tokenBridge/instructions/index.ts | 11 - .../tokenBridge/instructions/initialize.ts | 45 -- .../instructions/transferNative.ts | 121 ----- .../instructions/transferNativeWithPayload.ts | 128 ----- .../instructions/transferWrapped.ts | 132 ----- .../transferWrappedWithPayload.ts | 140 ----- .../src/utils/tokenBridge/program.ts | 36 -- .../solana/src/testing/client/token-bridge.ts | 4 +- platforms/solana/src/testing/helper.ts | 29 +- 87 files changed, 353 insertions(+), 4908 deletions(-) rename platforms/solana/{src/testing/accountVaaLayout.ts => protocols/core/src/accountLayout.ts} (92%) delete mode 100644 platforms/solana/protocols/core/src/postMessageLayout.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/claim.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/config.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/emitter.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/feeCollector.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/guardianSet.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/index.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/postedVaa.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/sequence.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/signatureSet.ts delete mode 100644 platforms/solana/protocols/core/src/utils/accounts/upgrade.ts delete mode 100644 platforms/solana/protocols/core/src/utils/coder/accounts.ts delete mode 100644 platforms/solana/protocols/core/src/utils/coder/events.ts delete mode 100644 platforms/solana/protocols/core/src/utils/coder/idl.ts delete mode 100644 platforms/solana/protocols/core/src/utils/coder/index.ts delete mode 100644 platforms/solana/protocols/core/src/utils/coder/instruction.ts delete mode 100644 platforms/solana/protocols/core/src/utils/coder/state.ts delete mode 100644 platforms/solana/protocols/core/src/utils/coder/types.ts delete mode 100644 platforms/solana/protocols/core/src/utils/cpi.ts delete mode 100644 platforms/solana/protocols/core/src/utils/index.ts delete mode 100644 platforms/solana/protocols/core/src/utils/instructions/feeTransfer.ts delete mode 100644 platforms/solana/protocols/core/src/utils/instructions/governance.ts delete mode 100644 platforms/solana/protocols/core/src/utils/instructions/index.ts delete mode 100644 platforms/solana/protocols/core/src/utils/instructions/initialize.ts delete mode 100644 platforms/solana/protocols/core/src/utils/instructions/postMessage.ts delete mode 100644 platforms/solana/protocols/core/src/utils/instructions/postVaa.ts delete mode 100644 platforms/solana/protocols/core/src/utils/instructions/secp256k1.ts delete mode 100644 platforms/solana/protocols/core/src/utils/instructions/verifySignature.ts delete mode 100644 platforms/solana/protocols/core/src/utils/program.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/foreignContract.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/index.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/redeemerConfig.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/registeredToken.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/senderConfig.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/signerSequence.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/tmpTokenAccount.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/tokenTransferMessage.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/index.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/index.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/transferNativeTokensWithRelay.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/transferWrappedTokensWithRelay.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/program.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/index.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/splMetadata.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/config.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/custody.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/endpoint.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/index.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/signer.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/transferWithPayload.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/wrapped.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/accounts.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/events.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/index.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/instruction.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/state.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/types.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/cpi.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/index.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/approve.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/attestToken.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/completeNative.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/completeWrapped.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/createWrapped.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/governance.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/index.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/initialize.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferNative.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferNativeWithPayload.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferWrapped.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferWrappedWithPayload.ts delete mode 100644 platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/program.ts diff --git a/core/base/src/utils/misc.ts b/core/base/src/utils/misc.ts index 1453bec6e..e3fb10023 100644 --- a/core/base/src/utils/misc.ts +++ b/core/base/src/utils/misc.ts @@ -26,15 +26,6 @@ export function throws(fn: () => any): boolean { } } -export function range(from: T, to: T): T[] { - function* generator(from: T, to: T) { - for (let i = from; from < to; i++) { - yield i; - } - } - return Array.from(generator(from, to)); -} - /** * Maps an object to another by applying the given function to every "leaf" property * (_i.e._ neither object nor array). diff --git a/package-lock.json b/package-lock.json index 3714b3393..59bc916ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@types/chai": "^4.3.5", "@types/jest": "^29.5.12", "@types/mocha": "^10.0.1", - "@types/node": "^20.17.9", + "@types/node": "^20.17.10", "@typescript-eslint/eslint-plugin": "^6.21.0", "chai": "^4.3.7", "jest": "^29.7.0", @@ -2516,9 +2516,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.17.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.9.tgz", - "integrity": "sha512-0JOXkRyLanfGPE2QRCwgxhzlBAvaRdCNMcvbd7jFfpmD4eEXll7LRwy5ymJmyeZqk7Nh7eD2LeUyQ68BbndmXw==", + "version": "20.17.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", + "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", "license": "MIT", "dependencies": { "undici-types": "~6.19.2" diff --git a/package.json b/package.json index 9a4bd6ea1..a9ff12748 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "@types/chai": "^4.3.5", "@types/jest": "^29.5.12", "@types/mocha": "^10.0.1", - "@types/node": "^20.17.9", + "@types/node": "^20.17.10", "@typescript-eslint/eslint-plugin": "^6.21.0", "chai": "^4.3.7", "jest": "^29.7.0", diff --git a/platforms/solana/protocols/core/package.json b/platforms/solana/protocols/core/package.json index e4d733e1e..9022654d8 100644 --- a/platforms/solana/protocols/core/package.json +++ b/platforms/solana/protocols/core/package.json @@ -47,7 +47,6 @@ "dependencies": { "@wormhole-foundation/sdk-connect": "1.0.3", "@wormhole-foundation/sdk-solana": "1.0.3", - "@coral-xyz/borsh": "0.30.1", "@coral-xyz/anchor": "0.30.1", "@solana/web3.js": "^1.95.8" }, diff --git a/platforms/solana/src/testing/accountVaaLayout.ts b/platforms/solana/protocols/core/src/accountLayout.ts similarity index 92% rename from platforms/solana/src/testing/accountVaaLayout.ts rename to platforms/solana/protocols/core/src/accountLayout.ts index af6cc02cc..b40d0677a 100644 --- a/platforms/solana/src/testing/accountVaaLayout.ts +++ b/platforms/solana/protocols/core/src/accountLayout.ts @@ -1,9 +1,6 @@ -import { - chainToChainId, - enumItem, - Layout, -} from '@wormhole-foundation/sdk-base'; -import { layoutItems } from '@wormhole-foundation/sdk-definitions'; +import type { Layout } from '@wormhole-foundation/sdk-connect'; +import { layoutItems } from '@wormhole-foundation/sdk-connect'; +import { chainToChainId, enumItem } from '@wormhole-foundation/sdk-base'; const versionItem = (custom: N) => ({ name: 'version', binary: 'uint', size: 1, custom, omit: true }) as const; @@ -81,6 +78,12 @@ const postedVaaV1Layout = [ ...emitterAddressAndPayloadLayout, ] as const satisfies Layout; +/** + * Covers: + * - A VAA; + * - A message; + * - An unreliable message. + */ export const accountDataLayout = { binary: 'switch', idSize: 3, diff --git a/platforms/solana/protocols/core/src/core.ts b/platforms/solana/protocols/core/src/core.ts index e656aa23c..0e1baf3d5 100644 --- a/platforms/solana/protocols/core/src/core.ts +++ b/platforms/solana/protocols/core/src/core.ts @@ -1,16 +1,32 @@ -import type { Program } from '@coral-xyz/anchor'; +import { Program } from '@coral-xyz/anchor'; +import { Keypair, Transaction, PublicKey } from '@solana/web3.js'; +import { + createVAA, + deserializeLayout, + toChain, +} from '@wormhole-foundation/sdk-connect'; +import { + SolanaAddress, + SolanaPlatform, + SolanaUnsignedTransaction, +} from '@wormhole-foundation/sdk-solana'; +import { accountDataLayout } from './accountLayout.js'; +import { IDL } from './types.js'; + import type { CompiledInstruction, Connection, MessageAccountKeys, MessageCompiledInstruction, - PublicKey, TransactionResponse, VersionedTransactionResponse, } from '@solana/web3.js'; -import { Keypair, Transaction } from '@solana/web3.js'; import type { - ChainId, + AnySolanaAddress, + SolanaChains, + SolanaTransaction, +} from '@wormhole-foundation/sdk-solana'; +import type { ChainsConfig, Contracts, Network, @@ -20,44 +36,17 @@ import type { WormholeCore, WormholeMessageId, } from '@wormhole-foundation/sdk-connect'; -import { - createVAA, - toChain, - toChainId, -} from '@wormhole-foundation/sdk-connect'; -import type { - AnySolanaAddress, - SolanaChains, - SolanaTransaction, -} from '@wormhole-foundation/sdk-solana'; -import { - SolanaAddress, - SolanaPlatform, - SolanaUnsignedTransaction, -} from '@wormhole-foundation/sdk-solana'; -import { deserializePostMessage } from './postMessageLayout.js'; import type { Wormhole as WormholeCoreContract } from './types.js'; -import type { BridgeData } from './utils/index.js'; -import { - createBridgeFeeTransferInstruction, - createPostMessageInstruction, - createPostVaaInstruction, - createReadOnlyWormholeProgramInterface, - createVerifySignaturesInstructions, - derivePostedVaaKey, - getGuardianSet, - getWormholeBridgeData, -} from './utils/index.js'; const SOLANA_SEQ_LOG = 'Program log: Sequence: '; export class SolanaWormholeCore implements WormholeCore { - readonly chainId: ChainId; readonly coreBridge: Program; - readonly address: string; - protected bridgeData?: BridgeData; + get address() { + return this.coreBridge.programId; + } constructor( readonly network: N, @@ -65,19 +54,15 @@ export class SolanaWormholeCore readonly connection: Connection, readonly contracts: Contracts, ) { - this.chainId = toChainId(chain); - - const coreBridgeAddress = contracts.coreBridge; - if (!coreBridgeAddress) + if (contracts.coreBridge === undefined) { throw new Error( `CoreBridge contract Address for chain ${chain} not found`, ); + } - this.address = coreBridgeAddress; - - this.coreBridge = createReadOnlyWormholeProgramInterface( - coreBridgeAddress, - connection, + this.coreBridge = new Program( + { ...IDL, address: contracts.coreBridge }, + { connection }, ); } @@ -123,7 +108,9 @@ export class SolanaWormholeCore } async getMessageFee(): Promise { + //return this.coreBridge.account.bridgeData.; await this.ensureBridgeConfig(); + return this.bridgeData!.config.fee; } @@ -356,7 +343,7 @@ export class SolanaWormholeCore sequence, nonce, payload, - } = deserializePostMessage(new Uint8Array(acctInfo?.data!)); + } = deserializeLayout(accountDataLayout, acctInfo?.data); return createVAA('Uint8Array', { guardianSet: await this.getGuardianSetIndex(), diff --git a/platforms/solana/protocols/core/src/index.ts b/platforms/solana/protocols/core/src/index.ts index 38b06f078..1ea0e11a6 100644 --- a/platforms/solana/protocols/core/src/index.ts +++ b/platforms/solana/protocols/core/src/index.ts @@ -6,5 +6,4 @@ registerProtocol(_platform, 'WormholeCore', SolanaWormholeCore); export * from './core.js'; export * from './types.js'; -export * as utils from './utils/index.js'; -export * from './postMessageLayout.js'; +export * from './accountLayout.js'; diff --git a/platforms/solana/protocols/core/src/postMessageLayout.ts b/platforms/solana/protocols/core/src/postMessageLayout.ts deleted file mode 100644 index bdbc7f190..000000000 --- a/platforms/solana/protocols/core/src/postMessageLayout.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { Layout, LayoutToType } from '@wormhole-foundation/sdk-connect'; -import { - deserializeLayout, - layoutItems, -} from '@wormhole-foundation/sdk-connect'; - -/** Binary layout for postMessage account */ -export const postMessageLayout = [ - { name: 'discriminator', binary: 'bytes', size: 4 }, - { name: 'consistencyLevel', binary: 'uint', size: 1, endianness: 'little' }, - { name: 'emitterAuthority', ...layoutItems.universalAddressItem }, - { name: 'messageStatus', binary: 'uint', size: 1, endianness: 'little' }, - { name: 'gap', binary: 'uint', size: 3 }, - { name: 'timestamp', binary: 'uint', size: 4, endianness: 'little' }, - { name: 'nonce', binary: 'uint', size: 4, endianness: 'little' }, - { name: 'sequence', binary: 'uint', size: 8, endianness: 'little' }, - { name: 'emitterChain', binary: 'uint', size: 2, endianness: 'little' }, - { name: 'emitterAddress', ...layoutItems.universalAddressItem }, - { name: 'payloadLength', binary: 'uint', size: 4, endianness: 'little' }, - { name: 'payload', binary: 'bytes' }, -] as const satisfies Layout; - -export function deserializePostMessage( - data: Uint8Array, -): LayoutToType { - return deserializeLayout(postMessageLayout, data); -} diff --git a/platforms/solana/protocols/core/src/types.ts b/platforms/solana/protocols/core/src/types.ts index dca47637d..0724632e3 100644 --- a/platforms/solana/protocols/core/src/types.ts +++ b/platforms/solana/protocols/core/src/types.ts @@ -1,9 +1,14 @@ export type Wormhole = { - version: '0.1.0'; - name: 'wormhole'; + address: string; + metadata: { + name: 'wormhole'; + version: '0.1.0'; + spec: '0.1.0'; + }; instructions: [ { name: 'initialize'; + discriminator: [0]; accounts: [ { name: 'bridge'; @@ -62,6 +67,7 @@ export type Wormhole = { }, { name: 'postMessage'; + discriminator: [1]; accounts: [ { name: 'bridge'; @@ -126,6 +132,7 @@ export type Wormhole = { }, { name: 'postVaa'; + discriminator: [2]; accounts: [ { name: 'guardianSet'; @@ -211,6 +218,7 @@ export type Wormhole = { }, { name: 'setFees'; + discriminator: [3]; accounts: [ { name: 'payer'; @@ -242,6 +250,7 @@ export type Wormhole = { }, { name: 'transferFees'; + discriminator: [4]; accounts: [ { name: 'payer'; @@ -288,6 +297,7 @@ export type Wormhole = { }, { name: 'upgradeContract'; + discriminator: [5]; accounts: [ { name: 'payer'; @@ -359,6 +369,7 @@ export type Wormhole = { }, { name: 'upgradeGuardianSet'; + discriminator: [6]; accounts: [ { name: 'payer'; @@ -400,6 +411,7 @@ export type Wormhole = { }, { name: 'verifySignatures'; + discriminator: [7]; accounts: [ { name: 'payer'; @@ -443,6 +455,7 @@ export type Wormhole = { }, { name: 'postMessageUnreliable'; + discriminator: [8]; accounts: [ { name: 'bridge'; @@ -507,8 +520,47 @@ export type Wormhole = { }, ]; accounts: [ + { + name: 'BridgeData'; + discriminator: []; + type: { + kind: 'struct'; + fields: [ + { + name: 'guardianSetIndex'; + type: 'u32'; + }, + { + name: 'lastLamports'; + type: 'u64'; + }, + { + name: 'config'; + type: 'BridgeConfig'; + }, + ]; + }; + }, + { + name: 'BridgeConfig'; + discriminator: []; + type: { + kind: 'struct'; + fields: [ + { + name: 'guardianSetExpirationTime'; + type: 'u32'; + }, + { + name: 'fee'; + type: 'u64'; + }, + ]; + }; + }, { name: 'PostedMessage'; + discriminator: []; type: { kind: 'struct'; fields: [ @@ -526,7 +578,7 @@ export type Wormhole = { }, { name: 'vaaSignatureAccount'; - type: 'publicKey'; + type: 'pubkey'; }, { name: 'submissionTime'; @@ -559,6 +611,7 @@ export type Wormhole = { }, { name: 'PostedVAA'; + discriminator: []; type: { kind: 'struct'; fields: [ @@ -576,7 +629,7 @@ export type Wormhole = { }, { name: 'vaaSignatureAccount'; - type: 'publicKey'; + type: 'pubkey'; }, { name: 'submissionTime'; @@ -611,11 +664,16 @@ export type Wormhole = { }; export const IDL: Wormhole = { - version: '0.1.0', - name: 'wormhole', + address: '', + metadata: { + name: 'wormhole', + version: '0.1.0', + spec: '0.1.0', + }, instructions: [ { name: 'initialize', + discriminator: [0], accounts: [ { name: 'bridge', @@ -674,6 +732,7 @@ export const IDL: Wormhole = { }, { name: 'postMessage', + discriminator: [1], accounts: [ { name: 'bridge', @@ -738,6 +797,7 @@ export const IDL: Wormhole = { }, { name: 'postVaa', + discriminator: [2], accounts: [ { name: 'guardianSet', @@ -823,6 +883,7 @@ export const IDL: Wormhole = { }, { name: 'setFees', + discriminator: [3], accounts: [ { name: 'payer', @@ -854,6 +915,7 @@ export const IDL: Wormhole = { }, { name: 'transferFees', + discriminator: [4], accounts: [ { name: 'payer', @@ -900,6 +962,7 @@ export const IDL: Wormhole = { }, { name: 'upgradeContract', + discriminator: [5], accounts: [ { name: 'payer', @@ -971,6 +1034,7 @@ export const IDL: Wormhole = { }, { name: 'upgradeGuardianSet', + discriminator: [6], accounts: [ { name: 'payer', @@ -1012,6 +1076,7 @@ export const IDL: Wormhole = { }, { name: 'verifySignatures', + discriminator: [7], accounts: [ { name: 'payer', @@ -1055,6 +1120,7 @@ export const IDL: Wormhole = { }, { name: 'postMessageUnreliable', + discriminator: [8], accounts: [ { name: 'bridge', @@ -1119,8 +1185,47 @@ export const IDL: Wormhole = { }, ], accounts: [ + { + name: 'BridgeData', + discriminator: [], + type: { + kind: 'struct', + fields: [ + { + name: 'guardianSetIndex', + type: 'u32', + }, + { + name: 'lastLamports', + type: 'u64', + }, + { + name: 'config', + type: 'BridgeConfig', + }, + ], + }, + }, + { + name: 'BridgeConfig', + discriminator: [], + type: { + kind: 'struct', + fields: [ + { + name: 'guardianSetExpirationTime', + type: 'u32', + }, + { + name: 'fee', + type: 'u64', + }, + ], + }, + }, { name: 'PostedMessage', + discriminator: [], type: { kind: 'struct', fields: [ @@ -1138,7 +1243,7 @@ export const IDL: Wormhole = { }, { name: 'vaaSignatureAccount', - type: 'publicKey', + type: 'pubkey', }, { name: 'submissionTime', @@ -1171,6 +1276,7 @@ export const IDL: Wormhole = { }, { name: 'PostedVAA', + discriminator: [], type: { kind: 'struct', fields: [ @@ -1188,7 +1294,7 @@ export const IDL: Wormhole = { }, { name: 'vaaSignatureAccount', - type: 'publicKey', + type: 'pubkey', }, { name: 'submissionTime', diff --git a/platforms/solana/protocols/core/src/utils/accounts/claim.ts b/platforms/solana/protocols/core/src/utils/accounts/claim.ts deleted file mode 100644 index 5b730bcf3..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/claim.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { - Commitment, - Connection, - PublicKey, - PublicKeyInitData, -} from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveClaimKey( - programId: PublicKeyInitData, - emitterAddress: Buffer | Uint8Array | string, - emitterChain: number, - sequence: bigint | number, -): PublicKey { - const address = - typeof emitterAddress == 'string' - ? Buffer.from(emitterAddress, 'hex') - : Buffer.from(emitterAddress); - if (address.length != 32) { - throw Error('address.length != 32'); - } - const sequenceSerialized = Buffer.alloc(8); - sequenceSerialized.writeBigUInt64BE( - typeof sequence == 'number' ? BigInt(sequence) : sequence, - ); - return utils.deriveAddress( - [ - address, - (() => { - const buf = Buffer.alloc(2); - buf.writeUInt16BE(emitterChain as number); - return buf; - })(), - sequenceSerialized, - ], - programId, - ); -} - -export async function getClaim( - connection: Connection, - programId: PublicKeyInitData, - emitterAddress: Buffer | Uint8Array | string, - emitterChain: number, - sequence: bigint | number, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo( - deriveClaimKey(programId, emitterAddress, emitterChain, sequence), - commitment, - ) - .then((info) => !!utils.getAccountData(info)[0]); -} diff --git a/platforms/solana/protocols/core/src/utils/accounts/config.ts b/platforms/solana/protocols/core/src/utils/accounts/config.ts deleted file mode 100644 index 48500b2a7..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/config.ts +++ /dev/null @@ -1,68 +0,0 @@ -import type { - Connection, - PublicKey, - Commitment, - PublicKeyInitData, -} from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveWormholeBridgeDataKey( - wormholeProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('Bridge')], wormholeProgramId); -} - -export async function getWormholeBridgeData( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo(deriveWormholeBridgeDataKey(wormholeProgramId), commitment) - .then((info) => BridgeData.deserialize(utils.getAccountData(info))); -} - -export class BridgeConfig { - guardianSetExpirationTime: number; - fee: bigint; - - constructor(guardianSetExpirationTime: number, fee: bigint) { - this.guardianSetExpirationTime = guardianSetExpirationTime; - this.fee = fee; - } - - static deserialize(data: Buffer): BridgeConfig { - if (data.length != 12) { - throw new Error('data.length != 12'); - } - const guardianSetExpirationTime = data.readUInt32LE(0); - const fee = data.readBigUInt64LE(4); - return new BridgeConfig(guardianSetExpirationTime, fee); - } -} - -export class BridgeData { - guardianSetIndex: number; - lastLamports: bigint; - config: BridgeConfig; - - constructor( - guardianSetIndex: number, - lastLamports: bigint, - config: BridgeConfig, - ) { - this.guardianSetIndex = guardianSetIndex; - this.lastLamports = lastLamports; - this.config = config; - } - - static deserialize(data: Buffer): BridgeData { - if (data.length != 24) { - throw new Error('data.length != 24'); - } - const guardianSetIndex = data.readUInt32LE(0); - const lastLamports = data.readBigUInt64LE(4); - const config = BridgeConfig.deserialize(data.subarray(12)); - return new BridgeData(guardianSetIndex, lastLamports, config); - } -} diff --git a/platforms/solana/protocols/core/src/utils/accounts/emitter.ts b/platforms/solana/protocols/core/src/utils/accounts/emitter.ts deleted file mode 100644 index 0d4d4b8dc..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/emitter.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { - Commitment, - Connection, - PublicKey, - PublicKeyInitData, -} from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; -import type { SequenceTracker } from './sequence.js'; -import { deriveEmitterSequenceKey, getSequenceTracker } from './sequence.js'; - -export interface EmitterAccounts { - emitter: PublicKey; - sequence: PublicKey; -} - -export function deriveWormholeEmitterKey( - emitterProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('emitter')], emitterProgramId); -} - -export function getEmitterKeys( - emitterProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, -): EmitterAccounts { - const emitter = deriveWormholeEmitterKey(emitterProgramId); - return { - emitter, - sequence: deriveEmitterSequenceKey(emitter, wormholeProgramId), - }; -} - -export async function getProgramSequenceTracker( - connection: Connection, - emitterProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - commitment?: Commitment, -): Promise { - return getSequenceTracker( - connection, - deriveWormholeEmitterKey(emitterProgramId), - wormholeProgramId, - commitment, - ); -} diff --git a/platforms/solana/protocols/core/src/utils/accounts/feeCollector.ts b/platforms/solana/protocols/core/src/utils/accounts/feeCollector.ts deleted file mode 100644 index 882902e37..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/feeCollector.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveFeeCollectorKey( - wormholeProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('fee_collector')], wormholeProgramId); -} diff --git a/platforms/solana/protocols/core/src/utils/accounts/guardianSet.ts b/platforms/solana/protocols/core/src/utils/accounts/guardianSet.ts deleted file mode 100644 index a50d82a0f..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/guardianSet.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { - Connection, - PublicKey, - Commitment, - PublicKeyInitData, -} from '@solana/web3.js'; -import { ETHEREUM_KEY_LENGTH } from '../instructions/secp256k1.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveGuardianSetKey( - wormholeProgramId: PublicKeyInitData, - index: number, -): PublicKey { - return utils.deriveAddress( - [ - Buffer.from('GuardianSet'), - (() => { - const buf = Buffer.alloc(4); - buf.writeUInt32BE(index); - return buf; - })(), - ], - wormholeProgramId, - ); -} - -export async function getGuardianSet( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - index: number, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo(deriveGuardianSetKey(wormholeProgramId, index), commitment) - .then((info) => GuardianSetData.deserialize(utils.getAccountData(info))); -} - -export class GuardianSetData { - index: number; - keys: Buffer[]; - creationTime: number; - expirationTime: number; - - constructor( - index: number, - keys: Buffer[], - creationTime: number, - expirationTime: number, - ) { - this.index = index; - this.keys = keys; - this.creationTime = creationTime; - this.expirationTime = expirationTime; - } - - static deserialize(data: Buffer): GuardianSetData { - const index = data.readUInt32LE(0); - const keysLen = data.readUInt32LE(4); - const keysEnd = 8 + keysLen * ETHEREUM_KEY_LENGTH; - const creationTime = data.readUInt32LE(keysEnd); - const expirationTime = data.readUInt32LE(4 + keysEnd); - - const keys = []; - for (let i = 0; i < keysLen; ++i) { - const start = 8 + i * ETHEREUM_KEY_LENGTH; - keys.push(data.subarray(start, start + ETHEREUM_KEY_LENGTH)); - } - return new GuardianSetData(index, keys, creationTime, expirationTime); - } -} diff --git a/platforms/solana/protocols/core/src/utils/accounts/index.ts b/platforms/solana/protocols/core/src/utils/accounts/index.ts deleted file mode 100644 index f8e65b370..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from './claim.js'; -export * from './config.js'; -export * from './emitter.js'; -export * from './feeCollector.js'; -export * from './guardianSet.js'; -export * from './postedVaa.js'; -export * from './sequence.js'; -export * from './signatureSet.js'; -export * from './upgrade.js'; diff --git a/platforms/solana/protocols/core/src/utils/accounts/postedVaa.ts b/platforms/solana/protocols/core/src/utils/accounts/postedVaa.ts deleted file mode 100644 index 387c6a1f9..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/postedVaa.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function derivePostedVaaKey( - wormholeProgramId: PublicKeyInitData, - hash: Buffer, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('PostedVAA'), hash], - wormholeProgramId, - ); -} diff --git a/platforms/solana/protocols/core/src/utils/accounts/sequence.ts b/platforms/solana/protocols/core/src/utils/accounts/sequence.ts deleted file mode 100644 index 25c91eba9..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/sequence.ts +++ /dev/null @@ -1,63 +0,0 @@ -import type { - Connection, - Commitment, - PublicKeyInitData, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveEmitterSequenceKey( - emitter: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('Sequence'), new PublicKey(emitter).toBytes()], - wormholeProgramId, - ); -} - -export async function getSequenceTracker( - connection: Connection, - emitter: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo( - deriveEmitterSequenceKey(emitter, wormholeProgramId), - commitment, - ) - .then((info) => SequenceTracker.deserialize(utils.getAccountData(info))); -} - -export class SequenceTracker { - sequence: bigint; - bump?: number; - emitterType?: number; - - constructor(sequence: bigint, bump?: number, emitterType?: number) { - this.sequence = sequence; - this.bump = bump; - this.emitterType = emitterType; - } - - static deserialize(data: Buffer): SequenceTracker { - if (data.length !== 8 && data.length !== 10) { - throw new Error('data.length != 8 or data.length != 10'); - } - - let bump, emitterType; - const sequence = data.readBigUInt64LE(0); - - if (data.length === 10) { - bump = data[8]; - emitterType = data[9]; - } - - return new SequenceTracker(sequence, bump, emitterType); - } - - value(): bigint { - return this.sequence; - } -} diff --git a/platforms/solana/protocols/core/src/utils/accounts/signatureSet.ts b/platforms/solana/protocols/core/src/utils/accounts/signatureSet.ts deleted file mode 100644 index 77094f317..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/signatureSet.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { - Connection, - Commitment, - PublicKeyInitData, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export async function getSignatureSetData( - connection: Connection, - signatureSet: PublicKeyInitData, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo(new PublicKey(signatureSet), commitment) - .then((info) => SignatureSetData.deserialize(utils.getAccountData(info))); -} - -export class SignatureSetData { - signatures: boolean[]; - hash: Buffer; - guardianSetIndex: number; - - constructor(signatures: boolean[], hash: Buffer, guardianSetIndex: number) { - this.signatures = signatures; - this.hash = hash; - this.guardianSetIndex = guardianSetIndex; - } - - static deserialize(data: Buffer): SignatureSetData { - const numSignatures = data.readUInt32LE(0); - const signatures = [...data.subarray(4, 4 + numSignatures)].map( - (x) => x != 0, - ); - const hashIndex = 4 + numSignatures; - const hash = data.subarray(hashIndex, hashIndex + 32); - const guardianSetIndex = data.readUInt32LE(hashIndex + 32); - return new SignatureSetData(signatures, hash, guardianSetIndex); - } -} diff --git a/platforms/solana/protocols/core/src/utils/accounts/upgrade.ts b/platforms/solana/protocols/core/src/utils/accounts/upgrade.ts deleted file mode 100644 index 03b71851b..000000000 --- a/platforms/solana/protocols/core/src/utils/accounts/upgrade.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveUpgradeAuthorityKey( - wormholeProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('upgrade')], wormholeProgramId); -} diff --git a/platforms/solana/protocols/core/src/utils/coder/accounts.ts b/platforms/solana/protocols/core/src/utils/coder/accounts.ts deleted file mode 100644 index add2b723c..000000000 --- a/platforms/solana/protocols/core/src/utils/coder/accounts.ts +++ /dev/null @@ -1,78 +0,0 @@ -import type { AccountsCoder, Idl } from '@coral-xyz/anchor'; -import { anchor } from '@wormhole-foundation/sdk-solana'; - -export class WormholeAccountsCoder - implements AccountsCoder -{ - constructor(private idl: Idl) {} - - public async encode(accountName: A, account: T): Promise { - switch (accountName) { - default: { - throw new Error(`Invalid account name: ${accountName}`); - } - } - } - - public decode(accountName: A, ix: Buffer): T { - return this.decodeUnchecked(accountName, ix); - } - - public decodeUnchecked(accountName: A, ix: Buffer): T { - switch (accountName) { - default: { - throw new Error(`Invalid account name: ${accountName}`); - } - } - } - - public memcmp(accountName: A, _appendData?: Buffer): any { - switch (accountName) { - case 'postVaa': { - return { - dataSize: 56, // + 4 + payload.length - }; - } - default: { - throw new Error(`Invalid account name: ${accountName}`); - } - } - } - - public size(idlAccount: anchor.IdlTypeDef): number { - return anchor.accountSize(this.idl, idlAccount) ?? 0; - } -} - -export interface PostVAAData { - version: number; - guardianSetIndex: number; - timestamp: number; - nonce: number; - emitterChain: number; - emitterAddress: Buffer; - sequence: bigint; - consistencyLevel: number; - payload: Buffer; -} - -export function encodePostVaaData(account: PostVAAData): Buffer { - const payload = account.payload; - const serialized = Buffer.alloc(60 + payload.length); - serialized.writeUInt8(account.version, 0); - serialized.writeUInt32LE(account.guardianSetIndex, 1); - serialized.writeUInt32LE(account.timestamp, 5); - serialized.writeUInt32LE(account.nonce, 9); - serialized.writeUInt16LE(account.emitterChain, 13); - serialized.write(account.emitterAddress.toString('hex'), 15, 'hex'); - serialized.writeBigUInt64LE(account.sequence, 47); - serialized.writeUInt8(account.consistencyLevel, 55); - serialized.writeUInt32LE(payload.length, 56); - serialized.write(payload.toString('hex'), 60, 'hex'); - - return serialized; -} - -export function decodePostVaaAccount(buf: Buffer): T { - return {} as T; -} diff --git a/platforms/solana/protocols/core/src/utils/coder/events.ts b/platforms/solana/protocols/core/src/utils/coder/events.ts deleted file mode 100644 index b0baf8f79..000000000 --- a/platforms/solana/protocols/core/src/utils/coder/events.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { EventCoder, Event, Idl } from '@coral-xyz/anchor'; -import type { anchor } from '@wormhole-foundation/sdk-solana'; - -export class WormholeEventsCoder implements EventCoder { - constructor(_idl: Idl) {} - - decode< - E extends anchor.IdlEvent = anchor.IdlEvent, - T = Record, - >(_log: string): Event | null { - throw new Error('Wormhole program does not have events'); - } -} diff --git a/platforms/solana/protocols/core/src/utils/coder/idl.ts b/platforms/solana/protocols/core/src/utils/coder/idl.ts deleted file mode 100644 index acce25026..000000000 --- a/platforms/solana/protocols/core/src/utils/coder/idl.ts +++ /dev/null @@ -1,112 +0,0 @@ -// Borrowed from coral-xyz/anchor -// -// https://github.com/coral-xyz/anchor/blob/master/ts/packages/anchor/src/coder/borsh/idl.ts - -import * as borsh from '@coral-xyz/borsh'; -import type { Layout } from 'buffer-layout'; -import type { anchor } from '@wormhole-foundation/sdk-solana'; -import { camelCase } from '@wormhole-foundation/sdk-solana'; - -export class IdlCoder { - public static fieldLayout( - field: { name?: string } & Pick, - types?: anchor.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( - { - name: undefined, - type: arrayTy, - }, - types, - ); - return borsh.array(innerLayout, arrayLen, fieldName); - } else { - throw new Error(`Not yet implemented: ${field}`); - } - } - } - } -} diff --git a/platforms/solana/protocols/core/src/utils/coder/index.ts b/platforms/solana/protocols/core/src/utils/coder/index.ts deleted file mode 100644 index c3bc9e837..000000000 --- a/platforms/solana/protocols/core/src/utils/coder/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { Coder, Idl } from '@coral-xyz/anchor'; -import { WormholeAccountsCoder } from './accounts.js'; -import { WormholeEventsCoder } from './events.js'; -import { WormholeInstructionCoder } from './instruction.js'; -import { WormholeStateCoder } from './state.js'; -import { WormholeTypesCoder } from './types.js'; - -export * from './instruction.js'; - -export class WormholeCoder implements Coder { - readonly instruction: WormholeInstructionCoder; - readonly accounts: WormholeAccountsCoder; - readonly state: WormholeStateCoder; - readonly events: WormholeEventsCoder; - readonly types: WormholeTypesCoder; - - constructor(idl: Idl) { - this.instruction = new WormholeInstructionCoder(idl); - this.accounts = new WormholeAccountsCoder(idl); - this.state = new WormholeStateCoder(idl); - this.events = new WormholeEventsCoder(idl); - this.types = new WormholeTypesCoder(idl); - } -} diff --git a/platforms/solana/protocols/core/src/utils/coder/instruction.ts b/platforms/solana/protocols/core/src/utils/coder/instruction.ts deleted file mode 100644 index 7af9e1d7d..000000000 --- a/platforms/solana/protocols/core/src/utils/coder/instruction.ts +++ /dev/null @@ -1,117 +0,0 @@ -import type { Idl, Instruction, InstructionCoder } from '@coral-xyz/anchor'; -import type { Layout } from 'buffer-layout'; -import { encoding } from '@wormhole-foundation/sdk-connect'; -import type { anchor } from '@wormhole-foundation/sdk-solana'; -import { camelCase, upperFirst } from '@wormhole-foundation/sdk-solana'; -import * as borsh from '@coral-xyz/borsh'; -import { IdlCoder } from './idl.js'; - -// Inspired by coral-xyz/anchor -// -// https://github.com/coral-xyz/anchor/blob/master/ts/packages/anchor/src/coder/borsh/instruction.ts -export class WormholeInstructionCoder implements InstructionCoder { - private ixLayout: Map; - - constructor(idl: Idl) { - this.ixLayout = WormholeInstructionCoder.parseIxLayout(idl); - } - - private static parseIxLayout(idl: Idl): Map { - const stateMethods = idl.instructions ? idl.instructions : []; - - const ixLayouts = stateMethods - .map((m: anchor.IdlStateMethod): [string, Layout] => { - let fieldLayouts = m.args.map((arg: anchor.IdlField) => { - return IdlCoder.fieldLayout( - arg, - Array.from([...(idl.accounts ?? []), ...(idl.types ?? [])]), - ); - }); - const name = camelCase(m.name); - return [name, borsh.struct(fieldLayouts, name)]; - }) - .concat( - idl.instructions.map((ix) => { - let fieldLayouts = ix.args.map((arg: anchor.IdlField) => - IdlCoder.fieldLayout( - arg, - Array.from([...(idl.accounts ?? []), ...(idl.types ?? [])]), - ), - ); - const name = camelCase(ix.name); - return [name, borsh.struct(fieldLayouts, name)]; - }), - ); - return new Map(ixLayouts); - } - - encode(ixName: string, ix: any): Buffer { - const buffer = Buffer.alloc(1000); // TODO: use a tighter buffer. - const methodName = camelCase(ixName); - const layout = this.ixLayout.get(methodName); - if (!layout) { - throw new Error(`Unknown method: ${methodName}`); - } - const len = layout.encode(ix, buffer); - const data = buffer.slice(0, len); - - return encodeWormholeInstructionData( - (WormholeInstruction as any)[upperFirst(methodName)], - data, - ); - } - - encodeState(_ixName: string, _ix: any): Buffer { - throw new Error('Wormhole program does not have state'); - } - - public decode( - ix: Buffer | Uint8Array, - _encoding: 'hex' | 'base58' = 'hex', - ): Instruction | null { - if (typeof ix === 'string') { - ix = - _encoding === 'hex' ? Buffer.from(ix, 'hex') : encoding.b58.decode(ix); - } - let discriminator = Buffer.from(ix.slice(0, 1)).readInt8(); - let data = Buffer.from(ix.slice(1)); - - let name = camelCase(WormholeInstruction[discriminator] ?? ''); - let layout = this.ixLayout.get(name); - - if (!layout) { - return null; - } - return { data: this.ixLayout.get(name)?.decode(data), name }; - } -} - -/** Solitaire enum of existing the Core Bridge's instructions. - * - * https://github.com/certusone/wormhole/blob/main/solana/bridge/program/src/lib.rs#L92 - */ -export enum WormholeInstruction { - Initialize, - PostMessage, - PostVaa, - SetFees, - TransferFees, - UpgradeContract, - UpgradeGuardianSet, - VerifySignatures, - PostMessageUnreliable, // sounds useful -} - -function encodeWormholeInstructionData( - discriminator: number, - data?: Buffer, -): Buffer { - const instructionData = Buffer.alloc( - 1 + (data === undefined ? 0 : data.length), - ); - instructionData.writeUInt8(discriminator, 0); - if (data !== undefined) { - instructionData.write(data.toString('hex'), 1, 'hex'); - } - return instructionData; -} diff --git a/platforms/solana/protocols/core/src/utils/coder/state.ts b/platforms/solana/protocols/core/src/utils/coder/state.ts deleted file mode 100644 index b0494a7ad..000000000 --- a/platforms/solana/protocols/core/src/utils/coder/state.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { Idl, StateCoder } from '@coral-xyz/anchor'; - -export class WormholeStateCoder implements StateCoder { - constructor(_idl: Idl) {} - - encode(_name: string, _account: T): Promise { - throw new Error('Wormhole program does not have state'); - } - decode(_ix: Buffer): T { - throw new Error('Wormhole program does not have state'); - } -} diff --git a/platforms/solana/protocols/core/src/utils/coder/types.ts b/platforms/solana/protocols/core/src/utils/coder/types.ts deleted file mode 100644 index 038f01fda..000000000 --- a/platforms/solana/protocols/core/src/utils/coder/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { Idl, TypesCoder } from '@coral-xyz/anchor'; - -export class WormholeTypesCoder implements TypesCoder { - constructor(_idl: Idl) {} - - encode(_name: string, _type: T): Buffer { - throw new Error('Wormhole program does not have user-defined types'); - } - decode(_name: string, _typeData: Buffer): T { - throw new Error('Wormhole program does not have user-defined types'); - } -} diff --git a/platforms/solana/protocols/core/src/utils/cpi.ts b/platforms/solana/protocols/core/src/utils/cpi.ts deleted file mode 100644 index d5717631a..000000000 --- a/platforms/solana/protocols/core/src/utils/cpi.ts +++ /dev/null @@ -1,96 +0,0 @@ -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; -import { - deriveFeeCollectorKey, - deriveWormholeBridgeDataKey, - getEmitterKeys, -} from './accounts/index.js'; -import { getPostMessageAccounts } from './instructions/index.js'; - -/** - * Accounts derived from Wormhole program. - */ -export interface WormholeDerivedAccounts { - /** - * seeds = ["Bridge"], seeds::program = wormholeProgram - */ - wormholeBridge: PublicKey; - /** - * seeds = ["emitter"], seeds::program = cpiProgramId - */ - wormholeEmitter: PublicKey; - /** - * seeds = ["Sequence", wormholeEmitter], seeds::program = wormholeProgram - */ - wormholeSequence: PublicKey; - /** - * seeds = ["fee_collector"], seeds::program = wormholeProgram - */ - wormholeFeeCollector: PublicKey; -} - -/** - * Generate Wormhole PDAs. - * - * @param cpiProgramId - * @param wormholeProgramId - * @returns - */ -export function getWormholeDerivedAccounts( - cpiProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, -): WormholeDerivedAccounts { - const { emitter: wormholeEmitter, sequence: wormholeSequence } = - getEmitterKeys(cpiProgramId, wormholeProgramId); - return { - wormholeBridge: deriveWormholeBridgeDataKey(wormholeProgramId), - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector: deriveFeeCollectorKey(wormholeProgramId), - }; -} - -/** - * Accounts needed to perform `post_message` instruction. - */ -export interface PostMessageCpiAccounts extends WormholeDerivedAccounts { - payer: PublicKey; - wormholeMessage: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; -} - -/** - * Generate accounts needed to perform `post_message` instruction - * as cross-program invocation. - * - * @param cpiProgramId - * @param wormholeProgramId - * @param payer - * @param message - * @returns - */ -export function getPostMessageCpiAccounts( - cpiProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, -): PostMessageCpiAccounts { - const accounts = getPostMessageAccounts( - wormholeProgramId, - payer, - message, - cpiProgramId, - ); - return { - payer: accounts.payer, - wormholeBridge: accounts.bridge, - wormholeMessage: accounts.message, - wormholeEmitter: accounts.emitter, - wormholeSequence: accounts.sequence, - wormholeFeeCollector: accounts.feeCollector, - clock: accounts.clock, - rent: accounts.rent, - systemProgram: accounts.systemProgram, - }; -} diff --git a/platforms/solana/protocols/core/src/utils/index.ts b/platforms/solana/protocols/core/src/utils/index.ts deleted file mode 100644 index 6fb532c35..000000000 --- a/platforms/solana/protocols/core/src/utils/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './accounts/index.js'; -export * from './cpi.js'; -export * from './instructions/index.js'; -export * from './program.js'; diff --git a/platforms/solana/protocols/core/src/utils/instructions/feeTransfer.ts b/platforms/solana/protocols/core/src/utils/instructions/feeTransfer.ts deleted file mode 100644 index e676a6646..000000000 --- a/platforms/solana/protocols/core/src/utils/instructions/feeTransfer.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey, SystemProgram } from '@solana/web3.js'; -import { deriveFeeCollectorKey } from './../accounts/index.js'; - -export function createBridgeFeeTransferInstruction( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - fee: bigint, -): TransactionInstruction { - return SystemProgram.transfer({ - fromPubkey: new PublicKey(payer), - toPubkey: deriveFeeCollectorKey(wormholeProgramId), - lamports: fee, - }); -} diff --git a/platforms/solana/protocols/core/src/utils/instructions/governance.ts b/platforms/solana/protocols/core/src/utils/instructions/governance.ts deleted file mode 100644 index 852a26da3..000000000 --- a/platforms/solana/protocols/core/src/utils/instructions/governance.ts +++ /dev/null @@ -1,258 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { - PublicKey, - SystemProgram, - SYSVAR_CLOCK_PUBKEY, - SYSVAR_RENT_PUBKEY, -} from '@solana/web3.js'; -import type { VAA } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; -import { SolanaAddress, utils } from '@wormhole-foundation/sdk-solana'; -import { - deriveClaimKey, - deriveFeeCollectorKey, - deriveGuardianSetKey, - derivePostedVaaKey, - deriveUpgradeAuthorityKey, - deriveWormholeBridgeDataKey, -} from './../accounts/index.js'; -import { createReadOnlyWormholeProgramInterface } from '../program.js'; - -export function createSetFeesInstruction( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'WormholeCore:SetMessageFee'>, -): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId, - connection, - ).methods.setFees(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getSetFeesAccounts(wormholeProgramId, payer, vaa) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface SetFeesAccounts { - payer: PublicKey; - bridge: PublicKey; - vaa: PublicKey; - claim: PublicKey; - systemProgram: PublicKey; -} - -export function getSetFeesAccounts( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'WormholeCore:SetMessageFee'>, -): SetFeesAccounts { - return { - payer: new PublicKey(payer), - bridge: deriveWormholeBridgeDataKey(wormholeProgramId), - vaa: derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: deriveClaimKey( - wormholeProgramId, - vaa.emitterAddress.toString(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - systemProgram: SystemProgram.programId, - }; -} - -export function createTransferFeesInstruction( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - recipient: PublicKeyInitData, - vaa: VAA<'WormholeCore:TransferFees'>, -): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId, - connection, - ).methods.transferFees(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getTransferFeesAccounts( - wormholeProgramId, - payer, - recipient, - vaa, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface TransferFeesAccounts { - payer: PublicKey; - bridge: PublicKey; - vaa: PublicKey; - claim: PublicKey; - feeCollector: PublicKey; - recipient: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; -} - -export function getTransferFeesAccounts( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - recipient: PublicKeyInitData, - vaa: VAA<'WormholeCore:TransferFees'>, -): TransferFeesAccounts { - return { - payer: new PublicKey(payer), - bridge: deriveWormholeBridgeDataKey(wormholeProgramId), - vaa: derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: deriveClaimKey( - wormholeProgramId, - vaa.emitterAddress.toString(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - feeCollector: deriveFeeCollectorKey(wormholeProgramId), - recipient: new PublicKey(recipient), - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - }; -} - -export function createUpgradeGuardianSetInstruction( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'WormholeCore:GuardianSetUpgrade'>, -): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId, - connection, - ).methods.upgradeGuardianSet(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getUpgradeGuardianSetAccounts( - wormholeProgramId, - payer, - vaa, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface UpgradeGuardianSetAccounts { - payer: PublicKey; - bridge: PublicKey; - vaa: PublicKey; - claim: PublicKey; - guardianSetOld: PublicKey; - guardianSetNew: PublicKey; - systemProgram: PublicKey; -} - -export function getUpgradeGuardianSetAccounts( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'WormholeCore:GuardianSetUpgrade'>, -): UpgradeGuardianSetAccounts { - return { - payer: new PublicKey(payer), - bridge: deriveWormholeBridgeDataKey(wormholeProgramId), - vaa: derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: deriveClaimKey( - wormholeProgramId, - vaa.emitterAddress.toString(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - guardianSetOld: deriveGuardianSetKey(wormholeProgramId, vaa.guardianSet), - guardianSetNew: deriveGuardianSetKey( - wormholeProgramId, - vaa.guardianSet + 1, - ), - systemProgram: SystemProgram.programId, - }; -} - -export function createUpgradeContractInstruction( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'WormholeCore:UpgradeContract'>, -): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId, - connection, - ).methods.upgradeContract(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getUpgradeContractAccounts(wormholeProgramId, payer, vaa) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface UpgradeContractAccounts { - payer: PublicKey; - bridge: PublicKey; - vaa: PublicKey; - claim: PublicKey; - upgradeAuthority: PublicKey; - spill: PublicKey; - implementation: PublicKey; - programData: PublicKey; - wormholeProgram: PublicKey; - rent: PublicKey; - clock: PublicKey; - bpfLoaderUpgradeable: PublicKey; - systemProgram: PublicKey; -} - -export function getUpgradeContractAccounts( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'WormholeCore:UpgradeContract'>, - spill?: PublicKeyInitData, -): UpgradeContractAccounts { - const { newContract } = vaa.payload.actionArgs; - - return { - payer: new PublicKey(payer), - bridge: deriveWormholeBridgeDataKey(wormholeProgramId), - vaa: derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: deriveClaimKey( - wormholeProgramId, - vaa.emitterAddress.toString(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - upgradeAuthority: deriveUpgradeAuthorityKey(wormholeProgramId), - spill: new PublicKey(spill === undefined ? payer : spill), - implementation: new SolanaAddress(newContract).unwrap(), - programData: utils.deriveProgramDataAddress(wormholeProgramId), - wormholeProgram: new PublicKey(wormholeProgramId), - rent: SYSVAR_RENT_PUBKEY, - clock: SYSVAR_CLOCK_PUBKEY, - bpfLoaderUpgradeable: utils.BPF_LOADER_UPGRADEABLE_PROGRAM_ID, - systemProgram: SystemProgram.programId, - }; -} diff --git a/platforms/solana/protocols/core/src/utils/instructions/index.ts b/platforms/solana/protocols/core/src/utils/instructions/index.ts deleted file mode 100644 index c2950df7d..000000000 --- a/platforms/solana/protocols/core/src/utils/instructions/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './feeTransfer.js'; -export * from './governance.js'; -export * from './initialize.js'; -export * from './postMessage.js'; -export * from './postVaa.js'; -export * from './verifySignature.js'; diff --git a/platforms/solana/protocols/core/src/utils/instructions/initialize.ts b/platforms/solana/protocols/core/src/utils/instructions/initialize.ts deleted file mode 100644 index 259665b75..000000000 --- a/platforms/solana/protocols/core/src/utils/instructions/initialize.ts +++ /dev/null @@ -1,68 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { - PublicKey, - SystemProgram, - SYSVAR_CLOCK_PUBKEY, - SYSVAR_RENT_PUBKEY, -} from '@solana/web3.js'; -import { createReadOnlyWormholeProgramInterface } from '../program.js'; -import { - deriveFeeCollectorKey, - deriveGuardianSetKey, - deriveWormholeBridgeDataKey, -} from './../accounts/index.js'; -import BN from 'bn.js'; - -export function createInitializeInstruction( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - guardianSetExpirationTime: number, - fee: bigint, - initialGuardians: Buffer[], -): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId, - connection, - ).methods.initialize(guardianSetExpirationTime, new BN(fee.toString()), [ - ...initialGuardians.map((b) => [...new Uint8Array(b)]), - ]); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getInitializeAccounts(wormholeProgramId, payer) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface InitializeAccounts { - bridge: PublicKey; - guardianSet: PublicKey; - feeCollector: PublicKey; - payer: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; -} - -export function getInitializeAccounts( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, -): InitializeAccounts { - return { - bridge: deriveWormholeBridgeDataKey(wormholeProgramId), - guardianSet: deriveGuardianSetKey(wormholeProgramId, 0), - feeCollector: deriveFeeCollectorKey(wormholeProgramId), - payer: new PublicKey(payer), - clock: SYSVAR_CLOCK_PUBKEY, - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - }; -} diff --git a/platforms/solana/protocols/core/src/utils/instructions/postMessage.ts b/platforms/solana/protocols/core/src/utils/instructions/postMessage.ts deleted file mode 100644 index 859d4e812..000000000 --- a/platforms/solana/protocols/core/src/utils/instructions/postMessage.ts +++ /dev/null @@ -1,81 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { - PublicKey, - SYSVAR_CLOCK_PUBKEY, - SYSVAR_RENT_PUBKEY, - SystemProgram, -} from '@solana/web3.js'; -import { - deriveWormholeBridgeDataKey, - deriveFeeCollectorKey, - deriveEmitterSequenceKey, - getEmitterKeys, -} from './../accounts/index.js'; -import { createReadOnlyWormholeProgramInterface } from '../program.js'; - -/** All accounts required to make a cross-program invocation with the Core Bridge program */ -export interface PostMessageAccounts { - bridge: PublicKey; - message: PublicKey; - emitter: PublicKey; - sequence: PublicKey; - payer: PublicKey; - feeCollector: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; -} - -export function createPostMessageInstruction( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - messageAccount: PublicKeyInitData, - payload: Uint8Array, - nonce: number, - consistencyLevel: number, -): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId, - connection, - ).methods.postMessage(nonce, Buffer.from(payload), consistencyLevel); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getPostMessageAccounts(wormholeProgramId, payer, messageAccount), - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export function getPostMessageAccounts( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - emitter?: PublicKeyInitData, -): PostMessageAccounts { - let sequence; - if (emitter) { - ({ emitter, sequence } = getEmitterKeys(emitter, wormholeProgramId)); - } else { - emitter = payer; - sequence = deriveEmitterSequenceKey(emitter, wormholeProgramId); - } - return { - bridge: deriveWormholeBridgeDataKey(wormholeProgramId), - message: new PublicKey(message), - emitter: new PublicKey(emitter), - sequence, - payer: new PublicKey(payer), - feeCollector: deriveFeeCollectorKey(wormholeProgramId), - clock: SYSVAR_CLOCK_PUBKEY, - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - }; -} diff --git a/platforms/solana/protocols/core/src/utils/instructions/postVaa.ts b/platforms/solana/protocols/core/src/utils/instructions/postVaa.ts deleted file mode 100644 index d10100927..000000000 --- a/platforms/solana/protocols/core/src/utils/instructions/postVaa.ts +++ /dev/null @@ -1,95 +0,0 @@ -import type { - PublicKeyInitData, - TransactionInstruction, - Connection, -} from '@solana/web3.js'; -import { - PublicKey, - SYSVAR_CLOCK_PUBKEY, - SYSVAR_RENT_PUBKEY, - SystemProgram, -} from '@solana/web3.js'; -import { createReadOnlyWormholeProgramInterface } from '../program.js'; -import { - deriveWormholeBridgeDataKey, - deriveGuardianSetKey, - derivePostedVaaKey, -} from './../accounts/index.js'; -import type { VAA } from '@wormhole-foundation/sdk-connect'; -import { serializePayload, toChainId } from '@wormhole-foundation/sdk-connect'; -import BN from 'bn.js'; - -/** - * Make {@link TransactionInstruction} for `post_vaa` instruction. - * - * `signatureSet` is a {@link @solana/web3.Keypair} generated outside of this method, which was used - * to write signatures and the message hash to. - * - * https://github.com/certusone/wormhole/blob/main/solana/bridge/program/src/api/post_vaa.rs - * - * @param {PublicKeyInitData} wormholeProgramId - wormhole program address - * @param {PublicKeyInitData} payer - transaction signer address - * @param {SignedVaa | ParsedVaa} vaa - either signed VAA bytes or parsed VAA - * @param {PublicKeyInitData} signatureSet - key for signature set account - */ -export function createPostVaaInstruction( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA, - signatureSet: PublicKeyInitData, -): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId, - connection, - ).methods.postVaa( - 1, // TODO: hardcoded VAA version - vaa.guardianSet, - vaa.timestamp, - vaa.nonce, - toChainId(vaa.emitterChain), - [...vaa.emitterAddress.toUint8Array()], - new BN(vaa.sequence.toString()), - vaa.consistencyLevel, - // Note: This _must_ be a Buffer, a Uint8Array does not work - Buffer.from(serializePayload(vaa.payloadLiteral, vaa.payload)), - ); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getPostVaaAccounts(wormholeProgramId, payer, signatureSet, vaa), - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface PostVaaAccounts { - guardianSet: PublicKey; - bridge: PublicKey; - signatureSet: PublicKey; - vaa: PublicKey; - payer: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; -} - -export function getPostVaaAccounts( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - signatureSet: PublicKeyInitData, - vaa: VAA, -): PostVaaAccounts { - return { - guardianSet: deriveGuardianSetKey(wormholeProgramId, vaa.guardianSet), - bridge: deriveWormholeBridgeDataKey(wormholeProgramId), - signatureSet: new PublicKey(signatureSet), - vaa: derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - payer: new PublicKey(payer), - clock: SYSVAR_CLOCK_PUBKEY, - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - }; -} diff --git a/platforms/solana/protocols/core/src/utils/instructions/secp256k1.ts b/platforms/solana/protocols/core/src/utils/instructions/secp256k1.ts deleted file mode 100644 index c6d0be051..000000000 --- a/platforms/solana/protocols/core/src/utils/instructions/secp256k1.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { TransactionInstruction, Secp256k1Program } from '@solana/web3.js'; - -export const SIGNATURE_LENGTH = 65; -export const ETHEREUM_KEY_LENGTH = 20; - -/** - * Create {@link TransactionInstruction} for {@link Secp256k1Program}. - * - * @param {Buffer[]} signatures - 65-byte signatures (64 bytes + 1 byte recovery id) - * @param {Buffer[]} keys - 20-byte ethereum public keys - * @param {Buffer} message - 32-byte hash - * @returns Solana instruction for Secp256k1 program - */ -export function createSecp256k1Instruction( - signatures: Buffer[], - keys: Buffer[], - message: Buffer, -): TransactionInstruction { - return new TransactionInstruction({ - keys: [], - programId: Secp256k1Program.programId, - data: Secp256k1SignatureOffsets.serialize(signatures, keys, message), - }); -} - -/** - * Secp256k1SignatureOffsets serializer - * - * See {@link https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program} for more info. - */ -export class Secp256k1SignatureOffsets { - // https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program - // - // struct Secp256k1SignatureOffsets { - // secp_signature_key_offset: u16, // offset to [signature,recovery_id,etherum_address] of 64+1+20 bytes - // secp_signature_instruction_index: u8, // instruction index to find data - // secp_pubkey_offset: u16, // offset to [signature,recovery_id] of 64+1 bytes - // secp_signature_instruction_index: u8, // instruction index to find data - // secp_message_data_offset: u16, // offset to start of message data - // secp_message_data_size: u16, // size of message data - // secp_message_instruction_index: u8, // index of instruction data to get message data - // } - // - // Pseudo code of the operation: - // - // process_instruction() { - // for i in 0..count { - // // i'th index values referenced: - // instructions = &transaction.message().instructions - // signature = instructions[secp_signature_instruction_index].data[secp_signature_offset..secp_signature_offset + 64] - // recovery_id = instructions[secp_signature_instruction_index].data[secp_signature_offset + 64] - // ref_eth_pubkey = instructions[secp_pubkey_instruction_index].data[secp_pubkey_offset..secp_pubkey_offset + 32] - // message_hash = keccak256(instructions[secp_message_instruction_index].data[secp_message_data_offset..secp_message_data_offset + secp_message_data_size]) - // pubkey = ecrecover(signature, recovery_id, message_hash) - // eth_pubkey = keccak256(pubkey[1..])[12..] - // if eth_pubkey != ref_eth_pubkey { - // return Error - // } - // } - // return Success - // } - - /** - * Serialize multiple signatures, ethereum public keys and message as Secp256k1 instruction data. - * - * @param {Buffer[]} signatures - 65-byte signatures (64 + 1 recovery id) - * @param {Buffer[]} keys - ethereum public keys - * @param {Buffer} message - 32-byte hash - * @returns serialized Secp256k1 instruction data - */ - static serialize(signatures: Buffer[], keys: Buffer[], message: Buffer) { - if (signatures.length == 0) { - throw Error('signatures.length == 0'); - } - - if (signatures.length != keys.length) { - throw Error('signatures.length != keys.length'); - } - - if (message.length != 32) { - throw Error('message.length != 32'); - } - - const numSignatures = signatures.length; - const offsetSpan = 11; - const dataLoc = 1 + numSignatures * offsetSpan; - - const dataLen = SIGNATURE_LENGTH + ETHEREUM_KEY_LENGTH; // 65 signature size + 20 eth pubkey size - const messageDataOffset = dataLoc + numSignatures * dataLen; - const messageDataSize = 32; - const serialized = Buffer.alloc(messageDataOffset + messageDataSize); - - serialized.writeUInt8(numSignatures, 0); - serialized.write(message.toString('hex'), messageDataOffset, 'hex'); - - for (let i = 0; i < numSignatures; ++i) { - const signature = signatures.at(i); - if (signature?.length != SIGNATURE_LENGTH) { - throw Error(`signatures[${i}].length != 65`); - } - - const key = keys.at(i); - if (key?.length != ETHEREUM_KEY_LENGTH) { - throw Error(`keys[${i}].length != 20`); - } - - const signatureOffset = dataLoc + dataLen * i; - const ethAddressOffset = signatureOffset + 65; - - serialized.writeUInt16LE(signatureOffset, 1 + i * offsetSpan); - serialized.writeUInt8(0, 3 + i * offsetSpan); - serialized.writeUInt16LE(ethAddressOffset, 4 + i * offsetSpan); - serialized.writeUInt8(0, 6 + i * offsetSpan); - serialized.writeUInt16LE(messageDataOffset, 7 + i * offsetSpan); - serialized.writeUInt16LE(messageDataSize, 9 + i * offsetSpan); - serialized.writeUInt8(0, 10 + i * offsetSpan); - - serialized.write(signature.toString('hex'), signatureOffset, 'hex'); - serialized.write(key.toString('hex'), ethAddressOffset, 'hex'); - } - - return serialized; - } -} diff --git a/platforms/solana/protocols/core/src/utils/instructions/verifySignature.ts b/platforms/solana/protocols/core/src/utils/instructions/verifySignature.ts deleted file mode 100644 index e9be79034..000000000 --- a/platforms/solana/protocols/core/src/utils/instructions/verifySignature.ts +++ /dev/null @@ -1,161 +0,0 @@ -import type { - Commitment, - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { - PublicKey, - SYSVAR_INSTRUCTIONS_PUBKEY, - SYSVAR_RENT_PUBKEY, - SystemProgram, -} from '@solana/web3.js'; -import type { VAA } from '@wormhole-foundation/sdk-connect'; -import { createReadOnlyWormholeProgramInterface } from '../program.js'; -import { deriveGuardianSetKey, getGuardianSet } from './../accounts/index.js'; -import { createSecp256k1Instruction } from './secp256k1.js'; - -const MAX_LEN_GUARDIAN_KEYS = 19; - -/** - * Signatures are batched in groups of 7 due to instruction - * data limits. These signatures are passed through to the Secp256k1 - * program to verify that the guardian public keys can be recovered. - * This instruction is paired with `verify_signatures` to validate the - * pubkey recovery. - * - * There are at most three pairs of instructions created. - * - * https://github.com/certusone/wormhole/blob/main/solana/bridge/program/src/api/verify_signature.rs - * - * - * @param {Connection} connection - Solana web3 connection - * @param {PublicKeyInitData} wormholeProgramId - wormhole program address - * @param {PublicKeyInitData} payer - transaction signer address - * @param {SignedVaa | ParsedVaa} vaa - either signed VAA bytes or parsed VAA - * @param {PublicKeyInitData} signatureSet - address to account of verified signatures - * @param {web3.ConfirmOptions} [options] - Solana confirmation options - */ -export async function createVerifySignaturesInstructions( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA, - signatureSet: PublicKeyInitData, - commitment?: Commitment, -): Promise { - const guardianSetIndex = vaa.guardianSet; - const guardianSetData = await getGuardianSet( - connection, - wormholeProgramId, - guardianSetIndex, - commitment, - ); - - const guardianSignatures = vaa.signatures; - const guardianKeys = guardianSetData.keys; - - const batchSize = 7; - const instructions: TransactionInstruction[] = []; - 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[] = []; - for (let j = 0; j < end - start; ++j) { - const item = guardianSignatures.at(j + start)!; - - signatures.push(Buffer.from(item.signature.encode())); - keys.push(guardianKeys.at(item.guardianIndex)!); - - signatureStatus[item.guardianIndex] = j; - } - - instructions.push( - createSecp256k1Instruction(signatures, keys, Buffer.from(vaa.hash)), - ); - - instructions.push( - createVerifySignaturesInstruction( - connection, - wormholeProgramId, - payer, - vaa, - signatureSet, - signatureStatus, - ), - ); - } - return instructions; -} - -/** - * Make {@link TransactionInstruction} for `verify_signatures` instruction. - * - * This is used in {@link createVerifySignaturesInstructions} for each batch of signatures being verified. - * `signatureSet` is a {@link @solana/web3.Keypair} generated outside of this method, used - * for writing signatures and the message hash to. - * - * https://github.com/certusone/wormhole/blob/main/solana/bridge/program/src/api/verify_signature.rs - * - * @param {PublicKeyInitData} wormholeProgramId - wormhole program address - * @param {PublicKeyInitData} payer - transaction signer address - * @param {SignedVaa | ParsedVaa} vaa - either signed VAA (Buffer) or parsed VAA - * @param {PublicKeyInitData} signatureSet - key for signature set account - * @param {Buffer} signatureStatus - array of guardian indices - * - */ -function createVerifySignaturesInstruction( - connection: Connection, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA, - signatureSet: PublicKeyInitData, - signatureStatus: number[], -): TransactionInstruction { - const methods = createReadOnlyWormholeProgramInterface( - wormholeProgramId, - connection, - ).methods.verifySignatures(signatureStatus); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getVerifySignatureAccounts( - wormholeProgramId, - payer, - signatureSet, - vaa, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface VerifySignatureAccounts { - payer: PublicKey; - guardianSet: PublicKey; - signatureSet: PublicKey; - instructions: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; -} - -export function getVerifySignatureAccounts( - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - signatureSet: PublicKeyInitData, - vaa: VAA, -): VerifySignatureAccounts { - return { - payer: new PublicKey(payer), - guardianSet: deriveGuardianSetKey(wormholeProgramId, vaa.guardianSet), - signatureSet: new PublicKey(signatureSet), - instructions: SYSVAR_INSTRUCTIONS_PUBKEY, - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - }; -} diff --git a/platforms/solana/protocols/core/src/utils/program.ts b/platforms/solana/protocols/core/src/utils/program.ts deleted file mode 100644 index 2526d7d0a..000000000 --- a/platforms/solana/protocols/core/src/utils/program.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { Connection, PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import type { Provider } from '@coral-xyz/anchor'; -import { Program } from '@coral-xyz/anchor'; -import { utils } from '@wormhole-foundation/sdk-solana'; -import { WormholeCoder } from './coder/index.js'; -import { type Wormhole, IDL } from '../types.js'; - -export function createWormholeProgramInterface( - programId: PublicKeyInitData, - provider?: Provider, -): Program { - return new Program( - IDL as Wormhole, - new PublicKey(programId), - provider === undefined ? ({ connection: null } as any) : provider, - coder(), - ); -} - -export function createReadOnlyWormholeProgramInterface( - programId: PublicKeyInitData, - connection?: Connection, -): Program { - return createWormholeProgramInterface( - programId, - utils.createReadOnlyProvider(connection), - ); -} - -export function coder(): WormholeCoder { - return new WormholeCoder(IDL as Wormhole); -} diff --git a/platforms/solana/protocols/tokenBridge/src/automaticTokenBridge.ts b/platforms/solana/protocols/tokenBridge/src/automaticTokenBridge.ts index 699d8ac97..df78937fb 100644 --- a/platforms/solana/protocols/tokenBridge/src/automaticTokenBridge.ts +++ b/platforms/solana/protocols/tokenBridge/src/automaticTokenBridge.ts @@ -3,18 +3,13 @@ import type { AutomaticTokenBridge, Chain, ChainAddress, - ChainId, ChainsConfig, Contracts, Network, Platform, TokenAddress, } from '@wormhole-foundation/sdk-connect'; -import { - isNative, - toChainId, - toNative, -} from '@wormhole-foundation/sdk-connect'; +import { isNative, toNative } from '@wormhole-foundation/sdk-connect'; import type { SolanaChains, SolanaTransaction, @@ -24,26 +19,13 @@ import { SolanaPlatform, SolanaUnsignedTransaction, } from '@wormhole-foundation/sdk-solana'; - -import type { Program } from '@coral-xyz/anchor'; +import { Program } from '@coral-xyz/anchor'; +import { TOKEN_BRIDGE_RELAYER_IDL } from './automaticTokenBridgeType.js'; import type { Connection } from '@solana/web3.js'; import { PublicKey, Transaction } from '@solana/web3.js'; import type { TokenBridgeRelayer as TokenBridgeRelayerContract } from './automaticTokenBridgeType.js'; -import type { - ForeignContract, - RedeemerConfig, - RegisteredToken, -} from './utils/automaticTokenBridge/index.js'; -import { - createTokenBridgeRelayerProgramInterface, - createTransferNativeTokensWithRelayInstruction, - createTransferWrappedTokensWithRelayInstruction, - deriveForeignContractAddress, - deriveRedeemerConfigAddress, - deriveRegisteredTokenAddress, -} from './utils/automaticTokenBridge/index.js'; import { NATIVE_MINT, @@ -66,8 +48,6 @@ export class SolanaAutomaticTokenBridge< C extends SolanaChains, > implements AutomaticTokenBridge { - readonly chainId: ChainId; - readonly coreBridgeProgramId: PublicKey; readonly tokenBridgeProgramId: PublicKey; readonly tokenBridgeRelayer: Program; @@ -78,22 +58,21 @@ export class SolanaAutomaticTokenBridge< readonly connection: Connection, readonly contracts: Contracts, ) { - this.chainId = toChainId(chain); - - const tokenBridgeRelayerAddress = contracts.tokenBridgeRelayer; - if (!tokenBridgeRelayerAddress) + if (contracts.tokenBridgeRelayer === undefined) { throw new Error( `TokenBridge contract Address for chain ${chain} not found`, ); + } - this.tokenBridgeRelayer = createTokenBridgeRelayerProgramInterface( - tokenBridgeRelayerAddress, - connection, + this.tokenBridgeRelayer = new Program( + { ...TOKEN_BRIDGE_RELAYER_IDL, address: contracts.tokenBridgeRelayer }, + { connection }, ); this.tokenBridgeProgramId = new PublicKey(contracts.tokenBridge!); this.coreBridgeProgramId = new PublicKey(contracts.coreBridge!); } + static async fromRpc( connection: Connection, config: ChainsConfig, diff --git a/platforms/solana/protocols/tokenBridge/src/automaticTokenBridgeType.ts b/platforms/solana/protocols/tokenBridge/src/automaticTokenBridgeType.ts index 2e5716543..879c6c3ea 100644 --- a/platforms/solana/protocols/tokenBridge/src/automaticTokenBridgeType.ts +++ b/platforms/solana/protocols/tokenBridge/src/automaticTokenBridgeType.ts @@ -1,6 +1,10 @@ export type TokenBridgeRelayer = { - version: '0.1.0'; - name: 'token_bridge_relayer'; + address: string; + metadata: { + name: 'token_bridge_relayer'; + version: '0.1.0'; + spec: '0.1.0'; + }; constants: [ { name: 'SEED_PREFIX_BRIDGED'; @@ -21,6 +25,7 @@ export type TokenBridgeRelayer = { instructions: [ { name: 'initialize'; + discriminator: [0]; docs: [ "This instruction is be used to generate your program's config.", 'And for convenience, we will store Wormhole-related PDAs in the', @@ -116,16 +121,17 @@ export type TokenBridgeRelayer = { args: [ { name: 'feeRecipient'; - type: 'publicKey'; + type: 'pubkey'; }, { name: 'assistant'; - type: 'publicKey'; + type: 'pubkey'; }, ]; }, { name: 'registerForeignContract'; + discriminator: [1]; docs: [ 'This instruction registers a new foreign contract (from another', 'network) and saves the emitter information in a ForeignEmitter account.', @@ -212,6 +218,7 @@ export type TokenBridgeRelayer = { }, { name: 'registerToken'; + discriminator: [2]; docs: [ 'This instruction registers a new token and saves the initial `swap_rate`', 'and `max_native_token_amount` in a RegisteredToken account.', @@ -292,6 +299,7 @@ export type TokenBridgeRelayer = { }, { name: 'deregisterToken'; + discriminator: [3]; docs: [ 'This instruction deregisters a token by closing the existing', '`RegisteredToken` account for a particular mint. This instruction is', @@ -341,6 +349,7 @@ export type TokenBridgeRelayer = { }, { name: 'updateRelayerFee'; + discriminator: [4]; docs: [ 'This instruction updates the `relayer_fee` in the `ForeignContract` account.', 'The `relayer_fee` is scaled by the `relayer_fee_precision`. For example,', @@ -403,6 +412,7 @@ export type TokenBridgeRelayer = { }, { name: 'updateRelayerFeePrecision'; + discriminator: [5]; docs: [ 'This instruction updates the `relayer_fee_precision` in the', '`SenderConfig` and `RedeemerConfig` accounts. The `relayer_fee_precision`', @@ -455,6 +465,7 @@ export type TokenBridgeRelayer = { }, { name: 'updateSwapRate'; + discriminator: [6]; docs: [ 'This instruction updates the `swap_rate` in the `RegisteredToken`', 'account. This instruction can only be called by the owner or', @@ -512,6 +523,7 @@ export type TokenBridgeRelayer = { }, { name: 'updateMaxNativeSwapAmount'; + discriminator: [7]; docs: [ 'This instruction updates the `max_native_swap_amount` in the', '`RegisteredToken` account. This instruction is owner-only,', @@ -574,6 +586,7 @@ export type TokenBridgeRelayer = { }, { name: 'setPauseForTransfers'; + discriminator: [8]; docs: [ 'This instruction updates the `paused` boolean in the `SenderConfig`', 'account. This instruction is owner-only, meaning that only the owner', @@ -611,6 +624,7 @@ export type TokenBridgeRelayer = { }, { name: 'submitOwnershipTransferRequest'; + discriminator: [9]; docs: [ 'This instruction sets the `pending_owner` field in the `OwnerConfig`', 'account. This instruction is owner-only, meaning that only the owner', @@ -642,12 +656,13 @@ export type TokenBridgeRelayer = { args: [ { name: 'newOwner'; - type: 'publicKey'; + type: 'pubkey'; }, ]; }, { name: 'confirmOwnershipTransferRequest'; + discriminator: [10]; docs: [ 'This instruction confirms that the `pending_owner` is the signer of', 'the transaction and updates the `owner` field in the `SenderConfig`,', @@ -697,6 +712,7 @@ export type TokenBridgeRelayer = { }, { name: 'cancelOwnershipTransferRequest'; + discriminator: [11]; docs: [ 'This instruction cancels the ownership transfer request by setting', 'the `pending_owner` field in the `OwnerConfig` account to `None`.', @@ -725,6 +741,7 @@ export type TokenBridgeRelayer = { }, { name: 'updateAssistant'; + discriminator: [12]; docs: [ 'This instruction updates the `assistant` field in the `OwnerConfig`', 'account. This instruction is owner-only, meaning that only the owner', @@ -756,12 +773,13 @@ export type TokenBridgeRelayer = { args: [ { name: 'newAssistant'; - type: 'publicKey'; + type: 'pubkey'; }, ]; }, { name: 'updateFeeRecipient'; + discriminator: [13]; docs: [ 'This instruction updates the `fee_recipient` field in the `RedeemerConfig`', 'account. This instruction is owner-only, meaning that only the owner', @@ -795,12 +813,13 @@ export type TokenBridgeRelayer = { args: [ { name: 'newFeeRecipient'; - type: 'publicKey'; + type: 'pubkey'; }, ]; }, { name: 'transferNativeTokensWithRelay'; + discriminator: [14]; docs: [ 'This instruction is used to transfer native tokens from Solana to a', 'foreign blockchain. The user can optionally specify a', @@ -1006,6 +1025,7 @@ export type TokenBridgeRelayer = { }, { name: 'transferWrappedTokensWithRelay'; + discriminator: [15]; docs: [ 'This instruction is used to transfer wrapped tokens from Solana to a', 'foreign blockchain. The user can optionally specify a', @@ -1197,6 +1217,7 @@ export type TokenBridgeRelayer = { }, { name: 'completeNativeTransferWithRelay'; + discriminator: [16]; docs: [ 'This instruction is used to redeem token transfers from foreign emitters.', 'It takes custody of the released native tokens and sends the tokens to the', @@ -1387,6 +1408,7 @@ export type TokenBridgeRelayer = { }, { name: 'completeWrappedTransferWithRelay'; + discriminator: [17]; docs: [ 'This instruction is used to redeem token transfers from foreign emitters.', 'It takes custody of the minted wrapped tokens and sends the tokens to the', @@ -1582,6 +1604,7 @@ export type TokenBridgeRelayer = { accounts: [ { name: 'foreignContract'; + discriminator: []; docs: ['Foreign emitter account data.']; type: { kind: 'struct'; @@ -1601,7 +1624,7 @@ export type TokenBridgeRelayer = { { name: 'tokenBridgeForeignEndpoint'; docs: ["Token Bridge program's foreign endpoint account key."]; - type: 'publicKey'; + type: 'pubkey'; }, { name: 'fee'; @@ -1618,6 +1641,7 @@ export type TokenBridgeRelayer = { }, { name: 'ownerConfig'; + discriminator: []; docs: ['Owner account data.']; type: { kind: 'struct'; @@ -1625,14 +1649,14 @@ export type TokenBridgeRelayer = { { name: 'owner'; docs: ["Program's owner."]; - type: 'publicKey'; + type: 'pubkey'; }, { name: 'assistant'; docs: [ "Program's assistant. Can be used to update the relayer fee and swap rate.", ]; - type: 'publicKey'; + type: 'pubkey'; }, { name: 'pendingOwner'; @@ -1640,7 +1664,7 @@ export type TokenBridgeRelayer = { 'Intermediate storage for the pending owner. Is used to transfer ownership.', ]; type: { - option: 'publicKey'; + option: 'pubkey'; }; }, ]; @@ -1648,13 +1672,14 @@ export type TokenBridgeRelayer = { }, { name: 'redeemerConfig'; + discriminator: []; type: { kind: 'struct'; fields: [ { name: 'owner'; docs: ["Program's owner."]; - type: 'publicKey'; + type: 'pubkey'; }, { name: 'bump'; @@ -1669,13 +1694,14 @@ export type TokenBridgeRelayer = { { name: 'feeRecipient'; docs: ['Recipient of all relayer fees and swap proceeds.']; - type: 'publicKey'; + type: 'pubkey'; }, ]; }; }, { name: 'registeredToken'; + discriminator: []; docs: ['Registered token account data.']; type: { kind: 'struct'; @@ -1699,13 +1725,14 @@ export type TokenBridgeRelayer = { }, { name: 'senderConfig'; + discriminator: []; type: { kind: 'struct'; fields: [ { name: 'owner'; docs: ["Program's owner."]; - type: 'publicKey'; + type: 'pubkey'; }, { name: 'bump'; @@ -1734,6 +1761,7 @@ export type TokenBridgeRelayer = { }, { name: 'signerSequence'; + discriminator: []; type: { kind: 'struct'; fields: [ @@ -1753,7 +1781,7 @@ export type TokenBridgeRelayer = { fields: [ { name: 'sequence'; - type: 'publicKey'; + type: 'pubkey'; }, ]; }; @@ -1982,8 +2010,12 @@ export type TokenBridgeRelayer = { }; export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { - version: '0.1.0', - name: 'token_bridge_relayer', + address: '', + metadata: { + name: 'token_bridge_relayer', + version: '0.1.0', + spec: '0.1.0', + }, constants: [ { name: 'SEED_PREFIX_BRIDGED', @@ -2004,6 +2036,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { instructions: [ { name: 'initialize', + discriminator: [0], docs: [ "This instruction is be used to generate your program's config.", 'And for convenience, we will store Wormhole-related PDAs in the', @@ -2099,16 +2132,17 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { args: [ { name: 'feeRecipient', - type: 'publicKey', + type: 'pubkey', }, { name: 'assistant', - type: 'publicKey', + type: 'pubkey', }, ], }, { name: 'registerForeignContract', + discriminator: [1], docs: [ 'This instruction registers a new foreign contract (from another', 'network) and saves the emitter information in a ForeignEmitter account.', @@ -2195,6 +2229,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'registerToken', + discriminator: [2], docs: [ 'This instruction registers a new token and saves the initial `swap_rate`', 'and `max_native_token_amount` in a RegisteredToken account.', @@ -2275,6 +2310,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'deregisterToken', + discriminator: [3], docs: [ 'This instruction deregisters a token by closing the existing', '`RegisteredToken` account for a particular mint. This instruction is', @@ -2324,6 +2360,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'updateRelayerFee', + discriminator: [4], docs: [ 'This instruction updates the `relayer_fee` in the `ForeignContract` account.', 'The `relayer_fee` is scaled by the `relayer_fee_precision`. For example,', @@ -2386,6 +2423,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'updateRelayerFeePrecision', + discriminator: [5], docs: [ 'This instruction updates the `relayer_fee_precision` in the', '`SenderConfig` and `RedeemerConfig` accounts. The `relayer_fee_precision`', @@ -2438,6 +2476,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'updateSwapRate', + discriminator: [6], docs: [ 'This instruction updates the `swap_rate` in the `RegisteredToken`', 'account. This instruction can only be called by the owner or', @@ -2495,6 +2534,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'updateMaxNativeSwapAmount', + discriminator: [7], docs: [ 'This instruction updates the `max_native_swap_amount` in the', '`RegisteredToken` account. This instruction is owner-only,', @@ -2557,6 +2597,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'setPauseForTransfers', + discriminator: [8], docs: [ 'This instruction updates the `paused` boolean in the `SenderConfig`', 'account. This instruction is owner-only, meaning that only the owner', @@ -2594,6 +2635,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'submitOwnershipTransferRequest', + discriminator: [9], docs: [ 'This instruction sets the `pending_owner` field in the `OwnerConfig`', 'account. This instruction is owner-only, meaning that only the owner', @@ -2625,12 +2667,13 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { args: [ { name: 'newOwner', - type: 'publicKey', + type: 'pubkey', }, ], }, { name: 'confirmOwnershipTransferRequest', + discriminator: [10], docs: [ 'This instruction confirms that the `pending_owner` is the signer of', 'the transaction and updates the `owner` field in the `SenderConfig`,', @@ -2680,6 +2723,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'cancelOwnershipTransferRequest', + discriminator: [11], docs: [ 'This instruction cancels the ownership transfer request by setting', 'the `pending_owner` field in the `OwnerConfig` account to `None`.', @@ -2708,6 +2752,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'updateAssistant', + discriminator: [12], docs: [ 'This instruction updates the `assistant` field in the `OwnerConfig`', 'account. This instruction is owner-only, meaning that only the owner', @@ -2739,12 +2784,13 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { args: [ { name: 'newAssistant', - type: 'publicKey', + type: 'pubkey', }, ], }, { name: 'updateFeeRecipient', + discriminator: [13], docs: [ 'This instruction updates the `fee_recipient` field in the `RedeemerConfig`', 'account. This instruction is owner-only, meaning that only the owner', @@ -2778,12 +2824,13 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { args: [ { name: 'newFeeRecipient', - type: 'publicKey', + type: 'pubkey', }, ], }, { name: 'transferNativeTokensWithRelay', + discriminator: [14], docs: [ 'This instruction is used to transfer native tokens from Solana to a', 'foreign blockchain. The user can optionally specify a', @@ -2989,6 +3036,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'transferWrappedTokensWithRelay', + discriminator: [15], docs: [ 'This instruction is used to transfer wrapped tokens from Solana to a', 'foreign blockchain. The user can optionally specify a', @@ -3180,6 +3228,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'completeNativeTransferWithRelay', + discriminator: [16], docs: [ 'This instruction is used to redeem token transfers from foreign emitters.', 'It takes custody of the released native tokens and sends the tokens to the', @@ -3370,6 +3419,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'completeWrappedTransferWithRelay', + discriminator: [17], docs: [ 'This instruction is used to redeem token transfers from foreign emitters.', 'It takes custody of the minted wrapped tokens and sends the tokens to the', @@ -3565,6 +3615,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { accounts: [ { name: 'foreignContract', + discriminator: [], docs: ['Foreign emitter account data.'], type: { kind: 'struct', @@ -3584,7 +3635,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { { name: 'tokenBridgeForeignEndpoint', docs: ["Token Bridge program's foreign endpoint account key."], - type: 'publicKey', + type: 'pubkey', }, { name: 'fee', @@ -3601,6 +3652,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'ownerConfig', + discriminator: [], docs: ['Owner account data.'], type: { kind: 'struct', @@ -3608,14 +3660,14 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { { name: 'owner', docs: ["Program's owner."], - type: 'publicKey', + type: 'pubkey', }, { name: 'assistant', docs: [ "Program's assistant. Can be used to update the relayer fee and swap rate.", ], - type: 'publicKey', + type: 'pubkey', }, { name: 'pendingOwner', @@ -3623,7 +3675,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { 'Intermediate storage for the pending owner. Is used to transfer ownership.', ], type: { - option: 'publicKey', + option: 'pubkey', }, }, ], @@ -3631,13 +3683,14 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'redeemerConfig', + discriminator: [], type: { kind: 'struct', fields: [ { name: 'owner', docs: ["Program's owner."], - type: 'publicKey', + type: 'pubkey', }, { name: 'bump', @@ -3652,13 +3705,14 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { { name: 'feeRecipient', docs: ['Recipient of all relayer fees and swap proceeds.'], - type: 'publicKey', + type: 'pubkey', }, ], }, }, { name: 'registeredToken', + discriminator: [], docs: ['Registered token account data.'], type: { kind: 'struct', @@ -3682,13 +3736,14 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'senderConfig', + discriminator: [], type: { kind: 'struct', fields: [ { name: 'owner', docs: ["Program's owner."], - type: 'publicKey', + type: 'pubkey', }, { name: 'bump', @@ -3717,6 +3772,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { }, { name: 'signerSequence', + discriminator: [], type: { kind: 'struct', fields: [ @@ -3736,7 +3792,7 @@ export const TOKEN_BRIDGE_RELAYER_IDL: TokenBridgeRelayer = { fields: [ { name: 'sequence', - type: 'publicKey', + type: 'pubkey', }, ], }, diff --git a/platforms/solana/protocols/tokenBridge/src/index.ts b/platforms/solana/protocols/tokenBridge/src/index.ts index 34b2b9211..9ded4496d 100644 --- a/platforms/solana/protocols/tokenBridge/src/index.ts +++ b/platforms/solana/protocols/tokenBridge/src/index.ts @@ -8,6 +8,5 @@ registerProtocol(_platform, 'AutomaticTokenBridge', SolanaAutomaticTokenBridge); export * from './tokenBridgeType.js'; export * from './automaticTokenBridgeType.js'; -export * from './utils/index.js'; export * from './tokenBridge.js'; export * from './automaticTokenBridge.js'; diff --git a/platforms/solana/protocols/tokenBridge/src/tokenBridge.ts b/platforms/solana/protocols/tokenBridge/src/tokenBridge.ts index a2f284ab8..2eef2dbd5 100644 --- a/platforms/solana/protocols/tokenBridge/src/tokenBridge.ts +++ b/platforms/solana/protocols/tokenBridge/src/tokenBridge.ts @@ -1,15 +1,3 @@ -import type { - Chain, - ChainAddress, - ChainId, - ChainsConfig, - Contracts, - NativeAddress, - Network, - Platform, - TokenBridge, - TokenId, -} from '@wormhole-foundation/sdk-connect'; import { ErrNotWrapped, UniversalAddress, @@ -19,22 +7,12 @@ import { toChainId, toNative, } from '@wormhole-foundation/sdk-connect'; -import type { - AnySolanaAddress, - SolanaChains, - SolanaTransaction, -} from '@wormhole-foundation/sdk-solana'; -import { - SolanaAddress, - SolanaPlatform, - SolanaUnsignedTransaction, -} from '@wormhole-foundation/sdk-solana'; import { - SolanaWormholeCore, - utils as coreUtils, -} from '@wormhole-foundation/sdk-solana-core'; - -import type { Program } from '@coral-xyz/anchor'; + Keypair, + PublicKey, + SystemProgram, + Transaction, +} from '@solana/web3.js'; import { ACCOUNT_SIZE, NATIVE_MINT, @@ -47,39 +25,47 @@ import { getMinimumBalanceForRentExemptAccount, getMint, } from '@solana/spl-token'; -import type { Connection, TransactionInstruction } from '@solana/web3.js'; +import { Program } from '@coral-xyz/anchor'; import { - Keypair, - PublicKey, - SystemProgram, - Transaction, -} from '@solana/web3.js'; - -import type { TokenBridge as TokenBridgeContract } from './tokenBridgeType.js'; + SolanaAddress, + SolanaPlatform, + SolanaUnsignedTransaction, +} from '@wormhole-foundation/sdk-solana'; import { - createApproveAuthoritySignerInstruction, - createAttestTokenInstruction, - createCompleteTransferNativeInstruction, - createCompleteTransferWrappedInstruction, - createCreateWrappedInstruction, - createReadOnlyTokenBridgeProgramInterface, - createTransferNativeInstruction, - createTransferNativeWithPayloadInstruction, - createTransferWrappedInstruction, - createTransferWrappedWithPayloadInstruction, - deriveWrappedMintKey, - getWrappedMeta, -} from './utils/index.js'; + SolanaWormholeCore, + utils as coreUtils, +} from '@wormhole-foundation/sdk-solana-core'; +import { TOKEN_BRIDGE_IDL } from './tokenBridgeType.js'; +import type { + Chain, + ChainAddress, + ChainId, + ChainsConfig, + Contracts, + NativeAddress, + Network, + Platform, + TokenBridge, + TokenId, +} from '@wormhole-foundation/sdk-connect'; +import type { Connection, TransactionInstruction } from '@solana/web3.js'; +import type { + AnySolanaAddress, + SolanaChains, + SolanaTransaction, +} from '@wormhole-foundation/sdk-solana'; +import type { TokenBridge as TokenBridgeContract } from './tokenBridgeType.js'; import '@wormhole-foundation/sdk-solana-core'; export class SolanaTokenBridge implements TokenBridge { - readonly chainId: ChainId; - readonly coreBridge: SolanaWormholeCore; readonly tokenBridge: Program; + get address() { + return this.tokenBridge.programId; + } constructor( readonly network: N, @@ -87,17 +73,14 @@ export class SolanaTokenBridge readonly connection: Connection, readonly contracts: Contracts, ) { - this.chainId = toChainId(chain); - - const tokenBridgeAddress = contracts.tokenBridge; - if (!tokenBridgeAddress) + if (contracts.tokenBridge === undefined) { throw new Error( `TokenBridge contract Address for chain ${chain} not found`, ); - - this.tokenBridge = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeAddress, - connection, + } + this.tokenBridge = new Program( + { ...TOKEN_BRIDGE_IDL, address: contracts.tokenBridge }, + { connection }, ); this.coreBridge = new SolanaWormholeCore( diff --git a/platforms/solana/protocols/tokenBridge/src/tokenBridgeType.ts b/platforms/solana/protocols/tokenBridge/src/tokenBridgeType.ts index c945be00b..311d52259 100644 --- a/platforms/solana/protocols/tokenBridge/src/tokenBridgeType.ts +++ b/platforms/solana/protocols/tokenBridge/src/tokenBridgeType.ts @@ -1,9 +1,14 @@ export type TokenBridge = { - version: '0.1.0'; - name: 'wormhole'; + address: string; + metadata: { + name: 'wormhole'; + version: '0.1.0'; + spec: '0.1.0'; + }; instructions: [ { name: 'initialize'; + discriminator: [0]; accounts: [ { name: 'payer'; @@ -29,12 +34,13 @@ export type TokenBridge = { args: [ { name: 'wormhole'; - type: 'publicKey'; + type: 'pubkey'; }, ]; }, { name: 'attestToken'; + discriminator: [1]; accounts: [ { name: 'payer'; @@ -116,6 +122,7 @@ export type TokenBridge = { }, { name: 'completeNative'; + discriminator: [2]; accounts: [ { name: 'payer'; @@ -192,6 +199,7 @@ export type TokenBridge = { }, { name: 'completeWrapped'; + discriminator: [3]; accounts: [ { name: 'payer'; @@ -268,6 +276,7 @@ export type TokenBridge = { }, { name: 'transferWrapped'; + discriminator: [4]; accounts: [ { name: 'payer'; @@ -382,6 +391,7 @@ export type TokenBridge = { }, { name: 'transferNative'; + discriminator: [5]; accounts: [ { name: 'payer'; @@ -496,6 +506,7 @@ export type TokenBridge = { }, { name: 'registerChain'; + discriminator: [6]; accounts: [ { name: 'payer'; @@ -542,6 +553,7 @@ export type TokenBridge = { }, { name: 'createWrapped'; + discriminator: [7]; accounts: [ { name: 'payer'; @@ -618,6 +630,7 @@ export type TokenBridge = { }, { name: 'upgradeContract'; + discriminator: [8]; accounts: [ { name: 'payer'; @@ -684,6 +697,7 @@ export type TokenBridge = { }, { name: 'transferWrappedWithPayload'; + discriminator: [9]; accounts: [ { name: 'payer'; @@ -802,13 +816,14 @@ export type TokenBridge = { { name: 'cpiProgramId'; type: { - option: 'publicKey'; + option: 'pubkey'; }; }, ]; }, { name: 'transferNativeWithPayload'; + discriminator: [10]; accounts: [ { name: 'payer'; @@ -927,7 +942,7 @@ export type TokenBridge = { { name: 'cpiProgramId'; type: { - option: 'publicKey'; + option: 'pubkey'; }; }, ]; @@ -937,11 +952,16 @@ export type TokenBridge = { }; export const TOKEN_BRIDGE_IDL: TokenBridge = { - version: '0.1.0', - name: 'wormhole', + address: '', + metadata: { + name: 'wormhole', + version: '0.1.0', + spec: '0.1.0', + }, instructions: [ { name: 'initialize', + discriminator: [0], accounts: [ { name: 'payer', @@ -967,12 +987,13 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { args: [ { name: 'wormhole', - type: 'publicKey', + type: 'pubkey', }, ], }, { name: 'attestToken', + discriminator: [1], accounts: [ { name: 'payer', @@ -1054,6 +1075,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { }, { name: 'completeNative', + discriminator: [2], accounts: [ { name: 'payer', @@ -1130,6 +1152,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { }, { name: 'completeWrapped', + discriminator: [3], accounts: [ { name: 'payer', @@ -1206,6 +1229,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { }, { name: 'transferWrapped', + discriminator: [4], accounts: [ { name: 'payer', @@ -1320,6 +1344,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { }, { name: 'transferNative', + discriminator: [5], accounts: [ { name: 'payer', @@ -1434,6 +1459,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { }, { name: 'registerChain', + discriminator: [6], accounts: [ { name: 'payer', @@ -1480,6 +1506,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { }, { name: 'createWrapped', + discriminator: [7], accounts: [ { name: 'payer', @@ -1556,6 +1583,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { }, { name: 'upgradeContract', + discriminator: [8], accounts: [ { name: 'payer', @@ -1622,6 +1650,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { }, { name: 'transferWrappedWithPayload', + discriminator: [9], accounts: [ { name: 'payer', @@ -1740,13 +1769,14 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { { name: 'cpiProgramId', type: { - option: 'publicKey', + option: 'pubkey', }, }, ], }, { name: 'transferNativeWithPayload', + discriminator: [10], accounts: [ { name: 'payer', @@ -1865,7 +1895,7 @@ export const TOKEN_BRIDGE_IDL: TokenBridge = { { name: 'cpiProgramId', type: { - option: 'publicKey', + option: 'pubkey', }, }, ], diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/foreignContract.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/foreignContract.ts deleted file mode 100644 index b75b6fc01..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/foreignContract.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { utils } from '@wormhole-foundation/sdk-solana'; -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; -import type { BN } from '@coral-xyz/anchor'; -import type { Chain } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; - -export interface ForeignContract { - chain: number; - address: number[]; - fee: BN; -} - -export function deriveForeignContractAddress( - programId: PublicKeyInitData, - chainId: Chain, -): PublicKey { - const chainIdBuf = Buffer.alloc(2); - chainIdBuf.writeUInt16BE(toChainId(chainId)); - return utils.deriveAddress( - [Buffer.from('foreign_contract'), chainIdBuf], - programId, - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/index.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/index.ts deleted file mode 100644 index 6e4abb805..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './foreignContract.js'; -export * from './redeemerConfig.js'; -export * from './registeredToken.js'; -export * from './senderConfig.js'; -export * from './tmpTokenAccount.js'; -export * from './tokenTransferMessage.js'; diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/redeemerConfig.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/redeemerConfig.ts deleted file mode 100644 index c18ba3ac1..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/redeemerConfig.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export interface RedeemerConfig { - owner: PublicKey; - bump: number; - relayerFeePrecision: number; - feeRecipient: PublicKey; -} - -export function deriveRedeemerConfigAddress( - programId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('redeemer')], programId); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/registeredToken.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/registeredToken.ts deleted file mode 100644 index 8d730ff25..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/registeredToken.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { BN } from '@coral-xyz/anchor'; -import type { PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export interface RegisteredToken { - swapRate: BN; - maxNativeSwapAmount: BN; -} - -export function deriveRegisteredTokenAddress( - programId: PublicKeyInitData, - mint: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('mint'), new PublicKey(mint).toBuffer()], - programId, - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/senderConfig.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/senderConfig.ts deleted file mode 100644 index c3cda68b9..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/senderConfig.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { utils } from '@wormhole-foundation/sdk-solana'; -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; - -export interface SenderConfig { - owner: PublicKey; - bump: number; - tokenBridge: any; - relayerFeePrecision: number; - paused: boolean; -} - -export function deriveSenderConfigAddress( - programId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('sender')], programId); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/signerSequence.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/signerSequence.ts deleted file mode 100644 index 561d1430b..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/signerSequence.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { utils } from '@wormhole-foundation/sdk-solana'; -import type { PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import type { BN } from '@coral-xyz/anchor'; - -export interface SignerSequence { - value: BN; -} - -export function deriveSignerSequenceAddress( - programId: PublicKeyInitData, - payerKey: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('seq'), new PublicKey(payerKey).toBuffer()], - programId, - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/tmpTokenAccount.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/tmpTokenAccount.ts deleted file mode 100644 index 4ce5f3825..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/tmpTokenAccount.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { utils } from '@wormhole-foundation/sdk-solana'; -import type { PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; - -export function deriveTmpTokenAccountAddress( - programId: PublicKeyInitData, - mint: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('tmp'), new PublicKey(mint).toBuffer()], - programId, - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/tokenTransferMessage.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/tokenTransferMessage.ts deleted file mode 100644 index 3529e7f17..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/accounts/tokenTransferMessage.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { utils } from '@wormhole-foundation/sdk-solana'; -import type { PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import type { BN } from '@coral-xyz/anchor'; -import { encoding } from '@wormhole-foundation/sdk-connect'; - -export function deriveTokenTransferMessageAddress( - programId: PublicKeyInitData, - payer: PublicKeyInitData, - sequence: BN, -): PublicKey { - return utils.deriveAddress( - [ - Buffer.from('bridged'), - new PublicKey(payer).toBuffer(), - Buffer.from(encoding.bignum.toBytes(BigInt(sequence.toString()), 8)), - ], - programId, - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/index.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/index.ts deleted file mode 100644 index 7d75ca0a8..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './accounts/index.js'; -export * from './instructions/index.js'; -export * from './program.js'; diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/index.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/index.ts deleted file mode 100644 index cb5ce807e..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './transferNativeTokensWithRelay.js'; -export * from './transferWrappedTokensWithRelay.js'; diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/transferNativeTokensWithRelay.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/transferNativeTokensWithRelay.ts deleted file mode 100644 index 292a10b48..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/transferNativeTokensWithRelay.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { getTransferNativeWithPayloadCpiAccounts } from '../../tokenBridge/cpi.js'; -import { createTokenBridgeRelayerProgramInterface } from '../program.js'; -import { - deriveForeignContractAddress, - deriveSenderConfigAddress, - deriveTokenTransferMessageAddress, - deriveRegisteredTokenAddress, - deriveTmpTokenAccountAddress, -} from './../accounts/index.js'; -import { getAssociatedTokenAddressSync } from '@solana/spl-token'; -import { deriveSignerSequenceAddress } from '../accounts/signerSequence.js'; -import type { Chain } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; - -import BN from 'bn.js'; - -export async function createTransferNativeTokensWithRelayInstruction( - connection: Connection, - programId: PublicKeyInitData, - payer: PublicKeyInitData, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - mint: PublicKeyInitData, - amount: bigint, - toNativeTokenAmount: bigint, - recipientAddress: Uint8Array, - recipientChain: Chain, - batchId: number, - wrapNative: boolean, -): Promise { - const { - methods: { transferNativeTokensWithRelay }, - account: { signerSequence }, - } = createTokenBridgeRelayerProgramInterface(programId, connection); - const signerSequenceAddress = deriveSignerSequenceAddress(programId, payer); - const sequence = await signerSequence - .fetch(signerSequenceAddress) - .then(({ value }) => value) - .catch((e) => { - if (e.message?.includes('Account does not exist')) { - // first time transferring - return new BN(0); - } - throw e; - }); - const message = deriveTokenTransferMessageAddress(programId, payer, sequence); - const fromTokenAccount = getAssociatedTokenAddressSync( - new PublicKey(mint), - new PublicKey(payer), - ); - const tmpTokenAccount = deriveTmpTokenAccountAddress(programId, mint); - const tokenBridgeAccounts = getTransferNativeWithPayloadCpiAccounts( - programId, - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - fromTokenAccount, - mint, - ); - return transferNativeTokensWithRelay( - new BN(amount.toString()), - new BN(toNativeTokenAmount.toString()), - toChainId(recipientChain), - [...recipientAddress], - batchId, - wrapNative, - ) - .accounts({ - config: deriveSenderConfigAddress(programId), - payerSequence: signerSequenceAddress, - foreignContract: deriveForeignContractAddress(programId, recipientChain), - registeredToken: deriveRegisteredTokenAddress(programId, mint), - tmpTokenAccount, - tokenBridgeProgram: new PublicKey(tokenBridgeProgramId), - ...tokenBridgeAccounts, - }) - .instruction(); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/transferWrappedTokensWithRelay.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/transferWrappedTokensWithRelay.ts deleted file mode 100644 index 09de010e9..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/instructions/transferWrappedTokensWithRelay.ts +++ /dev/null @@ -1,95 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { getTransferWrappedWithPayloadCpiAccounts } from '../../tokenBridge/cpi.js'; -import { createTokenBridgeRelayerProgramInterface } from '../program.js'; -import { - deriveForeignContractAddress, - deriveSenderConfigAddress, - deriveTokenTransferMessageAddress, - deriveTmpTokenAccountAddress, - deriveRegisteredTokenAddress, -} from './../accounts/index.js'; -import { getAssociatedTokenAddressSync } from '@solana/spl-token'; -import { getWrappedMeta } from './../../tokenBridge/index.js'; -import { deriveSignerSequenceAddress } from '../accounts/signerSequence.js'; -import type { Chain } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; - -import BN from 'bn.js'; - -export async function createTransferWrappedTokensWithRelayInstruction( - connection: Connection, - programId: PublicKeyInitData, - payer: PublicKeyInitData, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - mint: PublicKeyInitData, - amount: bigint, - toNativeTokenAmount: bigint, - recipientAddress: Uint8Array, - recipientChain: Chain, - batchId: number, -): Promise { - const { - methods: { transferWrappedTokensWithRelay }, - account: { signerSequence }, - } = createTokenBridgeRelayerProgramInterface(programId, connection); - const signerSequenceAddress = deriveSignerSequenceAddress(programId, payer); - const sequence = await signerSequence - .fetch(signerSequenceAddress) - .then(({ value }) => value) - .catch((e) => { - if (e.message?.includes('Account does not exist')) { - // first time transferring - return new BN(0); - } - throw e; - }); - - const message = deriveTokenTransferMessageAddress(programId, payer, sequence); - const fromTokenAccount = getAssociatedTokenAddressSync( - new PublicKey(mint), - new PublicKey(payer), - ); - const { chain, tokenAddress } = await getWrappedMeta( - connection, - tokenBridgeProgramId, - mint, - ); - const tmpTokenAccount = deriveTmpTokenAccountAddress(programId, mint); - const tokenBridgeAccounts = getTransferWrappedWithPayloadCpiAccounts( - programId, - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - fromTokenAccount, - chain, - tokenAddress, - ); - - return transferWrappedTokensWithRelay( - new BN(amount.toString()), - new BN(toNativeTokenAmount.toString()), - toChainId(recipientChain), - [...recipientAddress], - batchId, - ) - .accounts({ - config: deriveSenderConfigAddress(programId), - payerSequence: signerSequenceAddress, - foreignContract: deriveForeignContractAddress(programId, recipientChain), - registeredToken: deriveRegisteredTokenAddress( - programId, - new PublicKey(mint), - ), - tmpTokenAccount, - tokenBridgeProgram: new PublicKey(tokenBridgeProgramId), - ...tokenBridgeAccounts, - }) - .instruction(); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/program.ts b/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/program.ts deleted file mode 100644 index d08bc30c6..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/automaticTokenBridge/program.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Connection, PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { Program } from '@coral-xyz/anchor'; -import { - type TokenBridgeRelayer, - TOKEN_BRIDGE_RELAYER_IDL as IDL, -} from '../../automaticTokenBridgeType.js'; - -export function createTokenBridgeRelayerProgramInterface( - programId: PublicKeyInitData, - connection: Connection, -): Program { - return new Program(IDL, new PublicKey(programId), { connection }); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/index.ts b/platforms/solana/protocols/tokenBridge/src/utils/index.ts deleted file mode 100644 index f03ae45cc..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './automaticTokenBridge/index.js'; -export * from './tokenBridge/index.js'; -export * from './splMetadata.js'; diff --git a/platforms/solana/protocols/tokenBridge/src/utils/splMetadata.ts b/platforms/solana/protocols/tokenBridge/src/utils/splMetadata.ts deleted file mode 100644 index ab044b8e0..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/splMetadata.ts +++ /dev/null @@ -1,324 +0,0 @@ -import type { - AccountMeta, - Commitment, - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export class Creator { - address: PublicKey; - verified: boolean; - share: number; - - constructor(address: PublicKeyInitData, verified: boolean, share: number) { - this.address = new PublicKey(address); - this.verified = verified; - this.share = share; - } - - static size: number = 34; - - serialize() { - const serialized = Buffer.alloc(Creator.size); - serialized.write(this.address.toBuffer().toString('hex'), 0, 'hex'); - if (this.verified) { - serialized.writeUInt8(1, 32); - } - serialized.writeUInt8(this.share, 33); - return serialized; - } - - static deserialize(data: Buffer): Creator { - const address = data.subarray(0, 32); - const verified = data.readUInt8(32) > 0; - const share = data.readUInt8(33); - return new Creator(address, verified, share); - } -} - -export class Data { - name: string; - symbol: string; - uri: string; - sellerFeeBasisPoints: number; - creators: Creator[] | null; - - constructor( - name: string, - symbol: string, - uri: string, - sellerFeeBasisPoints: number, - creators: Creator[] | null, - ) { - this.name = name; - this.symbol = symbol; - this.uri = uri; - this.sellerFeeBasisPoints = sellerFeeBasisPoints; - this.creators = creators; - } - - serialize() { - const nameLen = this.name.length; - const symbolLen = this.symbol.length; - const uriLen = this.uri.length; - const creators = this.creators; - const [creatorsLen, creatorsSize] = (() => { - if (creators === null) { - return [0, 0]; - } - - const creatorsLen = creators.length; - return [creatorsLen, 4 + creatorsLen * Creator.size]; - })(); - const serialized = Buffer.alloc( - 15 + nameLen + symbolLen + uriLen + creatorsSize, - ); - serialized.writeUInt32LE(nameLen, 0); - serialized.write(this.name, 4); - serialized.writeUInt32LE(symbolLen, 4 + nameLen); - serialized.write(this.symbol, 8 + nameLen); - serialized.writeUInt32LE(uriLen, 8 + nameLen + symbolLen); - serialized.write(this.uri, 12 + nameLen + symbolLen); - serialized.writeUInt16LE( - this.sellerFeeBasisPoints, - 12 + nameLen + symbolLen + uriLen, - ); - if (creators === null) { - serialized.writeUInt8(0, 14 + nameLen + symbolLen + uriLen); - } else { - serialized.writeUInt8(1, 14 + nameLen + symbolLen + uriLen); - serialized.writeUInt32LE(creatorsLen, 15 + nameLen + symbolLen + uriLen); - for (let i = 0; i < creatorsLen; ++i) { - const creator = creators.at(i)!; - const idx = 19 + nameLen + symbolLen + uriLen + i * Creator.size; - serialized.write(creator.serialize().toString('hex'), idx, 'hex'); - } - } - return serialized; - } - - static deserialize(data: Buffer): Data { - const nameLen = data.readUInt32LE(0); - const name = data.subarray(4, 4 + nameLen).toString(); - const symbolLen = data.readUInt32LE(4 + nameLen); - const symbol = data - .subarray(8 + nameLen, 8 + nameLen + symbolLen) - .toString(); - const uriLen = data.readUInt32LE(8 + nameLen + symbolLen); - const uri = data - .subarray(12 + nameLen + symbolLen, 12 + nameLen + symbolLen + uriLen) - .toString(); - const sellerFeeBasisPoints = data.readUInt16LE( - 12 + nameLen + symbolLen + uriLen, - ); - const optionCreators = data.readUInt8(14 + nameLen + symbolLen + uriLen); - const creators = (() => { - if (optionCreators == 0) { - return null; - } - - const creators: Creator[] = []; - const creatorsLen = data.readUInt32LE(15 + nameLen + symbolLen + uriLen); - for (let i = 0; i < creatorsLen; ++i) { - const idx = 19 + nameLen + symbolLen + uriLen + i * Creator.size; - creators.push( - Creator.deserialize(data.subarray(idx, idx + Creator.size)), - ); - } - return creators; - })(); - return new Data(name, symbol, uri, sellerFeeBasisPoints, creators); - } -} - -export class CreateMetadataAccountArgs extends Data { - isMutable: boolean; - - constructor( - name: string, - symbol: string, - uri: string, - sellerFeeBasisPoints: number, - creators: Creator[] | null, - isMutable: boolean, - ) { - super(name, symbol, uri, sellerFeeBasisPoints, creators); - this.isMutable = isMutable; - } - - static serialize( - name: string, - symbol: string, - uri: string, - sellerFeeBasisPoints: number, - creators: Creator[] | null, - isMutable: boolean, - ) { - return new CreateMetadataAccountArgs( - name, - symbol, - uri, - sellerFeeBasisPoints, - creators, - isMutable, - ).serialize(); - } - - static serializeInstructionData( - name: string, - symbol: string, - uri: string, - sellerFeeBasisPoints: number, - creators: Creator[] | null, - isMutable: boolean, - ) { - return Buffer.concat([ - Buffer.alloc(1, 0), - CreateMetadataAccountArgs.serialize( - name, - symbol, - uri, - sellerFeeBasisPoints, - creators, - isMutable, - ), - ]); - } - - override serialize() { - return Buffer.concat([ - super.serialize(), - Buffer.alloc(1, this.isMutable ? 1 : 0), - ]); - } -} - -export class SplTokenMetadataProgram { - /** - * @internal - */ - constructor() {} - - /** - * Public key that identifies the SPL Token Metadata program - */ - static programId: PublicKey = new PublicKey( - 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s', - ); - - static createMetadataAccounts( - payer: PublicKey, - mint: PublicKey, - mintAuthority: PublicKey, - name: string, - symbol: string, - updateAuthority: PublicKey, - updateAuthorityIsSigner: boolean = false, - uri?: string, - creators?: Creator[] | null, - sellerFeeBasisPoints?: number, - isMutable: boolean = false, - metadataAccount: PublicKey = deriveSplTokenMetadataKey(mint), - ): TransactionInstruction { - const keys: AccountMeta[] = [ - utils.newAccountMeta(metadataAccount, false), - utils.newReadOnlyAccountMeta(mint, false), - utils.newReadOnlyAccountMeta(mintAuthority, true), - utils.newReadOnlyAccountMeta(payer, true), - utils.newReadOnlyAccountMeta(updateAuthority, updateAuthorityIsSigner), - utils.newReadOnlyAccountMeta(SystemProgram.programId, false), - utils.newReadOnlyAccountMeta(SYSVAR_RENT_PUBKEY, false), - ]; - const data = CreateMetadataAccountArgs.serializeInstructionData( - name, - symbol, - uri === undefined ? '' : uri, - sellerFeeBasisPoints === undefined ? 0 : sellerFeeBasisPoints, - creators === undefined ? null : creators, - isMutable, - ); - return { - programId: SplTokenMetadataProgram.programId, - keys, - data, - }; - } -} - -export function deriveSplTokenMetadataKey(mint: PublicKeyInitData): PublicKey { - return utils.deriveAddress( - [ - Buffer.from('metadata'), - SplTokenMetadataProgram.programId.toBuffer(), - new PublicKey(mint).toBuffer(), - ], - SplTokenMetadataProgram.programId, - ); -} - -export enum Key { - Uninitialized, - EditionV1, - MasterEditionV1, - ReservationListV1, - MetadataV1, - ReservationListV2, - MasterEditionV2, - EditionMarker, -} - -export class Metadata { - key: Key; - updateAuthority: PublicKey; - mint: PublicKey; - data: Data; - primarySaleHappened: boolean; - isMutable: boolean; - - constructor( - key: number, - updateAuthority: PublicKeyInitData, - mint: PublicKeyInitData, - data: Data, - primarySaleHappened: boolean, - isMutable: boolean, - ) { - this.key = key as Key; - this.updateAuthority = new PublicKey(updateAuthority); - this.mint = new PublicKey(mint); - this.data = data; - this.primarySaleHappened = primarySaleHappened; - this.isMutable = isMutable; - } - - static deserialize(data: Buffer): Metadata { - const key = data.readUInt8(0); - const updateAuthority = data.subarray(1, 33); - const mint = data.subarray(33, 65); - const meta = Data.deserialize(data.subarray(65)); - const metaLen = meta.serialize().length; - const primarySaleHappened = data.readUInt8(65 + metaLen) > 0; - const isMutable = data.readUInt8(66 + metaLen) > 0; - return new Metadata( - key, - updateAuthority, - mint, - meta, - primarySaleHappened, - isMutable, - ); - } -} - -export async function getMetadata( - connection: Connection, - mint: PublicKeyInitData, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo(deriveSplTokenMetadataKey(mint), commitment) - .then((info) => Metadata.deserialize(utils.getAccountData(info))); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/config.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/config.ts deleted file mode 100644 index 8ceb3f126..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/config.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { - Connection, - Commitment, - PublicKeyInitData, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveTokenBridgeConfigKey( - tokenBridgeProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('config')], tokenBridgeProgramId); -} - -export async function getTokenBridgeConfig( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo( - deriveTokenBridgeConfigKey(tokenBridgeProgramId), - commitment, - ) - .then((info) => TokenBridgeConfig.deserialize(utils.getAccountData(info))); -} - -export class TokenBridgeConfig { - wormhole: PublicKey; - - constructor(wormholeProgramId: Buffer) { - this.wormhole = new PublicKey(wormholeProgramId); - } - - static deserialize(data: Buffer): TokenBridgeConfig { - if (data.length != 32) { - throw new Error('data.length != 32'); - } - const wormholeProgramId = data.subarray(0, 32); - return new TokenBridgeConfig(wormholeProgramId); - } -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/custody.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/custody.ts deleted file mode 100644 index b0d8ec0f8..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/custody.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveCustodyKey( - tokenBridgeProgramId: PublicKeyInitData, - mint: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [new PublicKey(mint).toBuffer()], - tokenBridgeProgramId, - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/endpoint.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/endpoint.ts deleted file mode 100644 index 6c5a3c37d..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/endpoint.ts +++ /dev/null @@ -1,68 +0,0 @@ -import type { - Commitment, - Connection, - PublicKeyInitData, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import type { ChainId } from '@wormhole-foundation/sdk-connect'; -import { UniversalAddress, toChainId } from '@wormhole-foundation/sdk-connect'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveEndpointKey( - tokenBridgeProgramId: PublicKeyInitData, - emitterChain: number | ChainId, - emitterAddress: Buffer | Uint8Array | string, -): PublicKey { - if (emitterChain == toChainId('Solana')) { - throw new Error( - 'emitterChain == CHAIN_ID_SOLANA cannot exist as foreign token bridge emitter', - ); - } - const emitterAddr = - typeof emitterAddress === 'string' - ? new UniversalAddress(emitterAddress).toUint8Array() - : emitterAddress; - - return utils.deriveAddress( - [ - (() => { - const buf = Buffer.alloc(2); - buf.writeUInt16BE(emitterChain as number); - return buf; - })(), - emitterAddr, - ], - tokenBridgeProgramId, - ); -} - -export async function getEndpointRegistration( - connection: Connection, - endpointKey: PublicKeyInitData, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo(new PublicKey(endpointKey), commitment) - .then((info) => - EndpointRegistration.deserialize(utils.getAccountData(info)), - ); -} - -export class EndpointRegistration { - chain: ChainId; - contract: Buffer; - - constructor(chain: number, contract: Buffer) { - this.chain = chain as ChainId; - this.contract = contract; - } - - static deserialize(data: Buffer): EndpointRegistration { - if (data.length != 34) { - throw new Error('data.length != 34'); - } - const chain = data.readUInt16LE(0); - const contract = data.subarray(2, 34); - return new EndpointRegistration(chain, contract); - } -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/index.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/index.ts deleted file mode 100644 index 753d2218c..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './config.js'; -export * from './custody.js'; -export * from './endpoint.js'; -export * from './transferWithPayload.js'; -export * from './signer.js'; -export * from './wrapped.js'; diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/signer.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/signer.ts deleted file mode 100644 index 0c58cbeb2..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/signer.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveAuthoritySignerKey( - tokenBridgeProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('authority_signer')], - tokenBridgeProgramId, - ); -} - -export function deriveCustodySignerKey( - tokenBridgeProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('custody_signer')], - tokenBridgeProgramId, - ); -} - -export function deriveMintAuthorityKey( - tokenBridgeProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('mint_signer')], - tokenBridgeProgramId, - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/transferWithPayload.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/transferWithPayload.ts deleted file mode 100644 index 3f499240e..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/transferWithPayload.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { PublicKey, PublicKeyInitData } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveSenderAccountKey( - cpiProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('sender')], cpiProgramId); -} - -export function deriveRedeemerAccountKey( - cpiProgramId: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress([Buffer.from('redeemer')], cpiProgramId); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/wrapped.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/wrapped.ts deleted file mode 100644 index 574a50c3b..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/accounts/wrapped.ts +++ /dev/null @@ -1,94 +0,0 @@ -import type { - Commitment, - Connection, - PublicKeyInitData, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import type { ChainId } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; -import { utils } from '@wormhole-foundation/sdk-solana'; - -export function deriveWrappedMintKey( - tokenBridgeProgramId: PublicKeyInitData, - tokenChain: number | ChainId, - tokenAddress: Buffer | Uint8Array, -): PublicKey { - if (tokenChain == toChainId('Solana')) { - throw new Error( - 'tokenChain == CHAIN_ID_SOLANA does not have wrapped mint key', - ); - } - - return utils.deriveAddress( - [ - Buffer.from('wrapped'), - (() => { - const buf = Buffer.alloc(2); - buf.writeUInt16BE(tokenChain as number); - return buf; - })(), - tokenAddress as Uint8Array, - ], - tokenBridgeProgramId, - ); -} - -export function deriveWrappedMetaKey( - tokenBridgeProgramId: PublicKeyInitData, - mint: PublicKeyInitData, -): PublicKey { - return utils.deriveAddress( - [Buffer.from('meta'), new PublicKey(mint).toBuffer()], - tokenBridgeProgramId, - ); -} - -export async function getWrappedMeta( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - mint: PublicKeyInitData, - commitment?: Commitment, -): Promise { - return connection - .getAccountInfo( - deriveWrappedMetaKey(tokenBridgeProgramId, mint), - commitment, - ) - .then((info) => WrappedMeta.deserialize(utils.getAccountData(info))); -} - -export class WrappedMeta { - chain: number; - tokenAddress: Buffer; - originalDecimals: number; - lastUpdatedSequence?: bigint; - - constructor( - chain: number, - tokenAddress: Buffer, - originalDecimals: number, - lastUpdatedSequence?: bigint, - ) { - this.chain = chain; - this.tokenAddress = tokenAddress; - this.originalDecimals = originalDecimals; - this.lastUpdatedSequence = lastUpdatedSequence; - } - - static deserialize(data: Buffer): WrappedMeta { - if (data.length !== 35 && data.length !== 43) { - throw new Error(`invalid wrapped meta length: ${data.length}`); - } - const chain = data.readUInt16LE(0); - const tokenAddress = data.subarray(2, 34); - const originalDecimals = data.readUInt8(34); - const lastUpdatedSequence = - data.length === 43 ? data.readBigUInt64LE(35) : undefined; - return new WrappedMeta( - chain, - tokenAddress, - originalDecimals, - lastUpdatedSequence, - ); - } -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/accounts.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/accounts.ts deleted file mode 100644 index 6cd312e52..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/accounts.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { AccountsCoder, Idl } from '@coral-xyz/anchor'; -import { anchor } from '@wormhole-foundation/sdk-solana'; - -export class TokenBridgeAccountsCoder - implements AccountsCoder -{ - constructor(private idl: Idl) {} - - public async encode(accountName: A, account: T): Promise { - switch (accountName) { - default: { - throw new Error(`Invalid account name: ${accountName}`); - } - } - } - - public decode(accountName: A, ix: Buffer): T { - return this.decodeUnchecked(accountName, ix); - } - - public decodeUnchecked(accountName: A, ix: Buffer): T { - switch (accountName) { - default: { - throw new Error(`Invalid account name: ${accountName}`); - } - } - } - - public memcmp(accountName: A, _appendData?: Buffer): any { - switch (accountName) { - default: { - throw new Error(`Invalid account name: ${accountName}`); - } - } - } - - public size(idlAccount: anchor.IdlTypeDef): number { - return anchor.accountSize(this.idl, idlAccount) ?? 0; - } -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/events.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/events.ts deleted file mode 100644 index 27d28e57e..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/events.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { EventCoder, Event, Idl } from '@coral-xyz/anchor'; -import type { anchor } from '@wormhole-foundation/sdk-solana'; - -export class TokenBridgeEventsCoder implements EventCoder { - constructor(_idl: Idl) {} - - decode< - E extends anchor.IdlEvent = anchor.IdlEvent, - T = Record, - >(_log: string): Event | null { - throw new Error('Token Bridge program does not have events'); - } -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/index.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/index.ts deleted file mode 100644 index a05691d39..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { Coder, Idl } from '@coral-xyz/anchor'; -import { TokenBridgeAccountsCoder } from './accounts.js'; -import { TokenBridgeEventsCoder } from './events.js'; -import { TokenBridgeInstructionCoder } from './instruction.js'; -import { TokenBridgeStateCoder } from './state.js'; -import { TokenBridgeTypesCoder } from './types.js'; - -export * from './instruction.js'; - -export class TokenBridgeCoder implements Coder { - readonly instruction: TokenBridgeInstructionCoder; - readonly accounts: TokenBridgeAccountsCoder; - readonly state: TokenBridgeStateCoder; - readonly events: TokenBridgeEventsCoder; - readonly types: TokenBridgeTypesCoder; - - constructor(idl: Idl) { - this.instruction = new TokenBridgeInstructionCoder(idl); - this.accounts = new TokenBridgeAccountsCoder(idl); - this.state = new TokenBridgeStateCoder(idl); - this.events = new TokenBridgeEventsCoder(idl); - this.types = new TokenBridgeTypesCoder(idl); - } -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/instruction.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/instruction.ts deleted file mode 100644 index 472dfedbb..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/instruction.ts +++ /dev/null @@ -1,254 +0,0 @@ -import type { Idl, InstructionCoder } from '@coral-xyz/anchor'; -import { PublicKey } from '@solana/web3.js'; - -export class TokenBridgeInstructionCoder implements InstructionCoder { - constructor(_: Idl) {} - - encode(ixName: string, ix: any): Buffer { - switch (ixName) { - case 'initialize': { - return encodeInitialize(ix); - } - case 'attestToken': { - return encodeAttestToken(ix); - } - case 'completeNative': { - return encodeCompleteNative(ix); - } - case 'completeWrapped': { - return encodeCompleteWrapped(ix); - } - case 'transferWrapped': { - return encodeTransferWrapped(ix); - } - case 'transferNative': { - return encodeTransferNative(ix); - } - case 'registerChain': { - return encodeRegisterChain(ix); - } - case 'createWrapped': { - return encodeCreateWrapped(ix); - } - case 'upgradeContract': { - return encodeUpgradeContract(ix); - } - case 'transferWrappedWithPayload': { - return encodeTransferWrappedWithPayload(ix); - } - case 'transferNativeWithPayload': { - return encodeTransferNativeWithPayload(ix); - } - default: { - throw new Error(`Invalid instruction: ${ixName}`); - } - } - } - - encodeState(_ixName: string, _ix: any): Buffer { - throw new Error('Token Bridge program does not have state'); - } -} - -/** Solitaire enum of existing the Token Bridge's instructions. - * - * https://github.com/certusone/wormhole/blob/main/solana/modules/token_bridge/program/src/lib.rs#L100 - */ -export enum TokenBridgeInstruction { - Initialize, - AttestToken, - CompleteNative, - CompleteWrapped, - TransferWrapped, - TransferNative, - RegisterChain, - CreateWrapped, - UpgradeContract, - CompleteNativeWithPayload, - CompleteWrappedWithPayload, - TransferWrappedWithPayload, - TransferNativeWithPayload, -} - -function encodeTokenBridgeInstructionData( - instructionType: TokenBridgeInstruction, - data?: Buffer, -): Buffer { - const dataLen = data === undefined ? 0 : data.length; - const instructionData = Buffer.alloc(1 + dataLen); - instructionData.writeUInt8(instructionType, 0); - if (dataLen > 0) { - instructionData.write(data!.toString('hex'), 1, 'hex'); - } - return instructionData; -} - -function encodeInitialize({ wormhole }: any): Buffer { - const serialized = Buffer.alloc(32); - serialized.write( - new PublicKey(wormhole).toBuffer().toString('hex'), - 0, - 'hex', - ); - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.Initialize, - serialized, - ); -} - -function encodeAttestToken({ nonce }: any) { - const serialized = Buffer.alloc(4); - serialized.writeUInt32LE(nonce, 0); - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.AttestToken, - serialized, - ); -} - -function encodeCompleteNative({}: any) { - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.CompleteNative, - ); -} - -function encodeCompleteWrapped({}: any) { - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.CompleteWrapped, - ); -} - -function encodeTransferData({ - nonce, - amount, - fee, - targetAddress, - targetChain, -}: any) { - if (typeof amount != 'bigint') { - amount = BigInt(amount); - } - if (typeof fee != 'bigint') { - fee = BigInt(fee); - } - if (!Buffer.isBuffer(targetAddress)) { - throw new Error('targetAddress must be Buffer'); - } - const serialized = Buffer.alloc(54); - serialized.writeUInt32LE(nonce, 0); - serialized.writeBigUInt64LE(amount, 4); - serialized.writeBigUInt64LE(fee, 12); - serialized.write(targetAddress.toString('hex'), 20, 'hex'); - serialized.writeUInt16LE(targetChain, 52); - return serialized; -} - -function encodeTransferWrapped({ - nonce, - amount, - fee, - targetAddress, - targetChain, -}: any) { - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.TransferWrapped, - encodeTransferData({ nonce, amount, fee, targetAddress, targetChain }), - ); -} - -function encodeTransferNative({ - nonce, - amount, - fee, - targetAddress, - targetChain, -}: any) { - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.TransferNative, - encodeTransferData({ nonce, amount, fee, targetAddress, targetChain }), - ); -} - -function encodeRegisterChain({}: any) { - return encodeTokenBridgeInstructionData(TokenBridgeInstruction.RegisterChain); -} - -function encodeCreateWrapped({}: any) { - return encodeTokenBridgeInstructionData(TokenBridgeInstruction.CreateWrapped); -} - -function encodeUpgradeContract({}: any) { - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.UpgradeContract, - ); -} - -function encodeTransferWithPayloadData({ - nonce, - amount, - targetAddress, - targetChain, - payload, -}: any) { - if (typeof amount != 'bigint') { - amount = BigInt(amount); - } - if (!Buffer.isBuffer(targetAddress)) { - throw new Error('targetAddress must be Buffer'); - } - if (!Buffer.isBuffer(payload)) { - throw new Error('payload must be Buffer'); - } - const serializedWithPayloadLen = Buffer.alloc(50); - serializedWithPayloadLen.writeUInt32LE(nonce, 0); - serializedWithPayloadLen.writeBigUInt64LE(amount, 4); - serializedWithPayloadLen.write(targetAddress.toString('hex'), 12, 'hex'); - serializedWithPayloadLen.writeUInt16LE(targetChain, 44); - serializedWithPayloadLen.writeUInt32LE(payload.length, 46); - return Buffer.concat([ - serializedWithPayloadLen, - payload, - Buffer.alloc(1), // option == None - ]); -} - -function encodeTransferWrappedWithPayload({ - nonce, - amount, - fee, - targetAddress, - targetChain, - payload, -}: any) { - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.TransferWrappedWithPayload, - encodeTransferWithPayloadData({ - nonce, - amount, - fee, - targetAddress, - targetChain, - payload, - }), - ); -} - -function encodeTransferNativeWithPayload({ - nonce, - amount, - fee, - targetAddress, - targetChain, - payload, -}: any) { - return encodeTokenBridgeInstructionData( - TokenBridgeInstruction.TransferNativeWithPayload, - encodeTransferWithPayloadData({ - nonce, - amount, - fee, - targetAddress, - targetChain, - payload, - }), - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/state.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/state.ts deleted file mode 100644 index 21d41dab3..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/state.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { Idl, StateCoder } from '@coral-xyz/anchor'; - -export class TokenBridgeStateCoder implements StateCoder { - constructor(_idl: Idl) {} - - encode(_name: string, _account: T): Promise { - throw new Error('Token Bridge program does not have state'); - } - decode(_ix: Buffer): T { - throw new Error('Token Bridge program does not have state'); - } -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/types.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/types.ts deleted file mode 100644 index df924e348..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/coder/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { Idl, TypesCoder } from '@coral-xyz/anchor'; - -export class TokenBridgeTypesCoder implements TypesCoder { - constructor(_idl: Idl) {} - - encode(_name: string, _type: T): Buffer { - throw new Error('Token Bridge program does not have user-defined types'); - } - decode(_name: string, _typeData: Buffer): T { - throw new Error('Token Bridge program does not have user-defined types'); - } -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/cpi.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/cpi.ts deleted file mode 100644 index 7da7d6941..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/cpi.ts +++ /dev/null @@ -1,485 +0,0 @@ -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import type { PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from '@solana/web3.js'; -import { utils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveAuthoritySignerKey, - deriveCustodyKey, - deriveCustodySignerKey, - deriveEndpointKey, - deriveMintAuthorityKey, - deriveRedeemerAccountKey, - deriveSenderAccountKey, - deriveTokenBridgeConfigKey, - deriveWrappedMetaKey, - deriveWrappedMintKey, -} from './accounts/index.js'; -import { - getTransferNativeWithPayloadAccounts, - getTransferWrappedWithPayloadAccounts, -} from './instructions/index.js'; -import type { TokenBridge } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; - -/** - * Base Config Account for Token Bridge program. - */ -export interface TokenBridgeBaseDerivedAccounts { - /** - * seeds = ["config"], seeds::program = tokenBridgeProgram - */ - tokenBridgeConfig: PublicKey; -} - -/** - * Accounts derived from Token Bridge program for native assets. - */ -export interface TokenBridgeBaseNativeDerivedAccounts - extends TokenBridgeBaseDerivedAccounts { - /** - * seeds = ["custody_signer"], seeds::program = tokenBridgeProgram - */ - tokenBridgeCustodySigner: PublicKey; -} - -export interface TokenBridgeBaseSenderDerivedAccounts - extends TokenBridgeBaseDerivedAccounts { - /** - * seeds = ["authority_signer"], seeds::program = tokenBridgeProgram - */ - tokenBridgeAuthoritySigner: PublicKey; - /** - * seeds = ["sender"], seeds::program = cpiProgramId - */ - tokenBridgeSender: PublicKey; - /** - * seeds = ["Bridge"], seeds::program = wormholeProgram - */ - wormholeBridge: PublicKey; - /** - * seeds = ["emitter"], seeds::program = tokenBridgeProgram - */ - tokenBridgeEmitter: PublicKey; - /** - * seeds = ["Sequence", tokenBridgeEmitter], seeds::program = wormholeProgram - */ - tokenBridgeSequence: PublicKey; - /** - * seeds = ["fee_collector"], seeds::program = wormholeProgram - */ - wormholeFeeCollector: PublicKey; -} - -export interface TokenBridgeNativeSenderDerivedAccounts - extends TokenBridgeBaseNativeDerivedAccounts, - TokenBridgeBaseSenderDerivedAccounts {} - -export interface TokenBridgeWrappedSenderDerivedAccounts - extends TokenBridgeBaseSenderDerivedAccounts {} - -export interface TokenBridgeBaseRedeemerDerivedAccounts - extends TokenBridgeBaseDerivedAccounts { - /** - * seeds = ["redeemer"], seeds::program = cpiProgramId - */ - tokenBridgeRedeemer: PublicKey; -} - -export interface TokenBridgeNativeRedeemerDerivedAccounts - extends TokenBridgeBaseNativeDerivedAccounts, - TokenBridgeBaseRedeemerDerivedAccounts {} - -export interface TokenBridgeWrappedRedeemerDerivedAccounts - extends TokenBridgeBaseRedeemerDerivedAccounts { - /** - * seeds = ["mint_signer"], seeds::program = tokenBridgeProgram - */ - tokenBridgeMintAuthority: PublicKey; -} - -/** - * Accounts derived from Token Bridge program. - */ -export interface TokenBridgeDerivedAccounts - extends TokenBridgeNativeSenderDerivedAccounts, - TokenBridgeWrappedSenderDerivedAccounts, - TokenBridgeNativeRedeemerDerivedAccounts, - TokenBridgeWrappedRedeemerDerivedAccounts {} - -/** - * Generate Token Bridge PDAs. - * - * @param cpiProgramId - * @param tokenBridgeProgramId - * @param wormholeProgramId - * @returns - */ -export function getTokenBridgeDerivedAccounts( - cpiProgramId: PublicKeyInitData, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, -): TokenBridgeDerivedAccounts { - const { - wormholeEmitter: tokenBridgeEmitter, - wormholeBridge, - wormholeFeeCollector, - wormholeSequence: tokenBridgeSequence, - } = utils.getWormholeDerivedAccounts(tokenBridgeProgramId, wormholeProgramId); - return { - tokenBridgeConfig: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - tokenBridgeAuthoritySigner: deriveAuthoritySignerKey(tokenBridgeProgramId), - tokenBridgeCustodySigner: deriveCustodySignerKey(tokenBridgeProgramId), - tokenBridgeMintAuthority: deriveMintAuthorityKey(tokenBridgeProgramId), - tokenBridgeSender: deriveSenderAccountKey(cpiProgramId), - tokenBridgeRedeemer: deriveRedeemerAccountKey(cpiProgramId), - wormholeBridge, - tokenBridgeEmitter, - wormholeFeeCollector, - tokenBridgeSequence, - }; -} - -/** - * Accounts needed to perform `transfer_native_with_payload` instruction. - */ -export interface TransferNativeWithPayloadCpiAccounts - extends TokenBridgeNativeSenderDerivedAccounts { - payer: PublicKey; - /** - * seeds = [mint], seeds::program = tokenBridgeProgram - */ - tokenBridgeCustody: PublicKey; - /** - * Token account where tokens reside - */ - fromTokenAccount: PublicKey; - mint: PublicKey; - wormholeMessage: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -/** - * Generate accounts needed to perform `transfer_wrapped_with_payload` instruction - * as cross-program invocation. - * - * @param cpiProgramId - * @param tokenBridgeProgramId - * @param wormholeProgramId - * @param payer - * @param message - * @param fromTokenAccount - * @param mint - * @returns - */ -export function getTransferNativeWithPayloadCpiAccounts( - cpiProgramId: PublicKeyInitData, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - fromTokenAccount: PublicKeyInitData, - mint: PublicKeyInitData, -): TransferNativeWithPayloadCpiAccounts { - const accounts = getTransferNativeWithPayloadAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - fromTokenAccount, - mint, - cpiProgramId, - ); - return { - payer: accounts.payer, - tokenBridgeConfig: accounts.config, - fromTokenAccount: accounts.from, - mint: accounts.mint, - tokenBridgeCustody: accounts.custody, - tokenBridgeAuthoritySigner: accounts.authoritySigner, - tokenBridgeCustodySigner: accounts.custodySigner, - wormholeBridge: accounts.wormholeBridge, - wormholeMessage: accounts.wormholeMessage, - tokenBridgeEmitter: accounts.wormholeEmitter, - tokenBridgeSequence: accounts.wormholeSequence, - wormholeFeeCollector: accounts.wormholeFeeCollector, - clock: accounts.clock, - tokenBridgeSender: accounts.sender, - rent: accounts.rent, - systemProgram: accounts.systemProgram, - tokenProgram: accounts.tokenProgram, - wormholeProgram: accounts.wormholeProgram, - }; -} - -/** - * Accounts needed to perform `transfer_wrapped_with_payload` instruction. - */ -export interface TransferWrappedWithPayloadCpiAccounts - extends TokenBridgeWrappedSenderDerivedAccounts { - payer: PublicKey; - /** - * Token account where tokens reside - */ - fromTokenAccount: PublicKey; - /** - * Token account owner (usually cpiProgramId) - */ - fromTokenAccountOwner: PublicKey; - /** - * seeds = ["wrapped", token_chain, token_address], seeds::program = tokenBridgeProgram - */ - tokenBridgeWrappedMint: PublicKey; - /** - * seeds = ["meta", mint], seeds::program = tokenBridgeProgram - */ - tokenBridgeWrappedMeta: PublicKey; - wormholeMessage: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -/** - * Generate accounts needed to perform `transfer_wrapped_with_payload` instruction - * as cross-program invocation. - * - * @param cpiProgramId - * @param tokenBridgeProgramId - * @param wormholeProgramId - * @param payer - * @param message - * @param fromTokenAccount - * @param tokenChain - * @param tokenAddress - * @param [fromTokenAccountOwner] - * @returns - */ -export function getTransferWrappedWithPayloadCpiAccounts( - cpiProgramId: PublicKeyInitData, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - fromTokenAccount: PublicKeyInitData, - tokenChain: number, - tokenAddress: Buffer | Uint8Array, - fromTokenAccountOwner?: PublicKeyInitData, -): TransferWrappedWithPayloadCpiAccounts { - const accounts = getTransferWrappedWithPayloadAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - fromTokenAccount, - fromTokenAccountOwner === undefined ? cpiProgramId : fromTokenAccountOwner, - tokenChain, - tokenAddress, - cpiProgramId, - ); - return { - payer: accounts.payer, - tokenBridgeConfig: accounts.config, - fromTokenAccount: accounts.from, - fromTokenAccountOwner: accounts.fromOwner, - tokenBridgeWrappedMint: accounts.mint, - tokenBridgeWrappedMeta: accounts.wrappedMeta, - tokenBridgeAuthoritySigner: accounts.authoritySigner, - wormholeBridge: accounts.wormholeBridge, - wormholeMessage: accounts.wormholeMessage, - tokenBridgeEmitter: accounts.wormholeEmitter, - tokenBridgeSequence: accounts.wormholeSequence, - wormholeFeeCollector: accounts.wormholeFeeCollector, - clock: accounts.clock, - tokenBridgeSender: accounts.sender, - rent: accounts.rent, - systemProgram: accounts.systemProgram, - tokenProgram: accounts.tokenProgram, - wormholeProgram: accounts.wormholeProgram, - }; -} - -/** - * Accounts needed to perform `complete_native_with_payload` instruction. - */ -export interface CompleteTransferNativeWithPayloadCpiAccounts - extends TokenBridgeNativeRedeemerDerivedAccounts { - payer: PublicKey; - /** - * seeds = ["PostedVAA", vaa_hash], seeds::program = wormholeProgram - */ - vaa: PublicKey; - /** - * seeds = [emitter_address, emitter_chain, sequence], seeds::program = tokenBridgeProgram - */ - tokenBridgeClaim: PublicKey; - /** - * seeds = [emitter_chain, emitter_address], seeds::program = tokenBridgeProgram - */ - tokenBridgeForeignEndpoint: PublicKey; - /** - * Token account to receive tokens - */ - toTokenAccount: PublicKey; - toFeesTokenAccount: PublicKey; // this shouldn't exist? - /** - * seeds = [mint], seeds::program = tokenBridgeProgram - */ - tokenBridgeCustody: PublicKey; - mint: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -/** - * Generate accounts needed to perform `complete_native_with_payload` instruction - * as cross-program invocation. - * - * Note: `toFeesTokenAccount` is the same as `toTokenAccount`. For your program, - * you only need to pass your `toTokenAccount` into the complete transfer - * instruction for the `toFeesTokenAccount`. - * - * @param tokenBridgeProgramId - * @param wormholeProgramId - * @param payer - * @param vaa - * @param toTokenAccount - * @returns - */ -export function getCompleteTransferNativeWithPayloadCpiAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: TokenBridge.TransferVAA, - toTokenAccount: PublicKeyInitData, -): CompleteTransferNativeWithPayloadCpiAccounts { - const mint = new PublicKey(vaa.payload.token.address.toUint8Array()); - const cpiProgramId = new PublicKey(vaa.payload.to.address.toUint8Array()); - - return { - payer: new PublicKey(payer), - tokenBridgeConfig: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - vaa: utils.derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - tokenBridgeClaim: utils.deriveClaimKey( - tokenBridgeProgramId, - vaa.emitterAddress.toUint8Array(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - tokenBridgeForeignEndpoint: deriveEndpointKey( - tokenBridgeProgramId, - toChainId(vaa.emitterChain), - vaa.emitterAddress.toUint8Array(), - ), - toTokenAccount: new PublicKey(toTokenAccount), - tokenBridgeRedeemer: deriveRedeemerAccountKey(cpiProgramId), - toFeesTokenAccount: new PublicKey(toTokenAccount), - tokenBridgeCustody: deriveCustodyKey(tokenBridgeProgramId, mint), - mint, - tokenBridgeCustodySigner: deriveCustodySignerKey(tokenBridgeProgramId), - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} - -/** - * Accounts needed to perform `complete_wrapped_with_payload` instruction. - */ -export interface CompleteTransferWrappedWithPayloadCpiAccounts - extends TokenBridgeWrappedRedeemerDerivedAccounts { - payer: PublicKey; - /** - * seeds = ["PostedVAA", vaa_hash], seeds::program = wormholeProgram - */ - vaa: PublicKey; - /** - * seeds = [emitter_address, emitter_chain, sequence], seeds::program = tokenBridgeProgram - */ - tokenBridgeClaim: PublicKey; - /** - * seeds = [emitter_chain, emitter_address], seeds::program = tokenBridgeProgram - */ - tokenBridgeForeignEndpoint: PublicKey; - /** - * Token account to receive tokens - */ - toTokenAccount: PublicKey; - toFeesTokenAccount: PublicKey; // this shouldn't exist? - /** - * seeds = ["wrapped", token_chain, token_address], seeds::program = tokenBridgeProgram - */ - tokenBridgeWrappedMint: PublicKey; - /** - * seeds = ["meta", mint], seeds::program = tokenBridgeProgram - */ - tokenBridgeWrappedMeta: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -/** - * Generate accounts needed to perform `complete_wrapped_with_payload` instruction - * as cross-program invocation. - * - * Note: `toFeesTokenAccount` is the same as `toTokenAccount`. For your program, - * you only need to pass your `toTokenAccount` into the complete transfer - * instruction for the `toFeesTokenAccount`. - * - * @param cpiProgramId - * @param tokenBridgeProgramId - * @param wormholeProgramId - * @param payer - * @param vaa - * @returns - */ -export function getCompleteTransferWrappedWithPayloadCpiAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: TokenBridge.TransferVAA, - toTokenAccount: PublicKeyInitData, -): CompleteTransferWrappedWithPayloadCpiAccounts { - const mint = deriveWrappedMintKey( - tokenBridgeProgramId, - toChainId(vaa.payload.token.chain), - vaa.payload.token.address.toUint8Array(), - ); - const cpiProgramId = new PublicKey(vaa.payload.to.address.toUint8Array()); - return { - payer: new PublicKey(payer), - tokenBridgeConfig: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - vaa: utils.derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - tokenBridgeClaim: utils.deriveClaimKey( - tokenBridgeProgramId, - vaa.emitterAddress.toUint8Array(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - tokenBridgeForeignEndpoint: deriveEndpointKey( - tokenBridgeProgramId, - toChainId(vaa.emitterChain), - vaa.emitterAddress.toUint8Array(), - ), - toTokenAccount: new PublicKey(toTokenAccount), - tokenBridgeRedeemer: deriveRedeemerAccountKey(cpiProgramId), - toFeesTokenAccount: new PublicKey(toTokenAccount), - tokenBridgeWrappedMint: mint, - tokenBridgeWrappedMeta: deriveWrappedMetaKey(tokenBridgeProgramId, mint), - tokenBridgeMintAuthority: deriveMintAuthorityKey(tokenBridgeProgramId), - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/index.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/index.ts deleted file mode 100644 index 6fb532c35..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './accounts/index.js'; -export * from './cpi.js'; -export * from './instructions/index.js'; -export * from './program.js'; diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/approve.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/approve.ts deleted file mode 100644 index a0f36334d..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/approve.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createApproveInstruction } from '@solana/spl-token'; -import type { PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { deriveAuthoritySignerKey } from './../accounts/index.js'; - -export function createApproveAuthoritySignerInstruction( - tokenBridgeProgramId: PublicKeyInitData, - tokenAccount: PublicKeyInitData, - owner: PublicKeyInitData, - amount: number | bigint, -) { - return createApproveInstruction( - new PublicKey(tokenAccount), - deriveAuthoritySignerKey(tokenBridgeProgramId), - new PublicKey(owner), - amount, - ); -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/attestToken.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/attestToken.ts deleted file mode 100644 index 07976ceff..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/attestToken.ts +++ /dev/null @@ -1,108 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; -import { utils as coreUtils } from '@wormhole-foundation/sdk-solana-core'; -import { deriveSplTokenMetadataKey } from '../../splMetadata.js'; -import { - deriveTokenBridgeConfigKey, - deriveWrappedMetaKey, -} from './../accounts/index.js'; - -export function createAttestTokenInstruction( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - mint: PublicKeyInitData, - message: PublicKeyInitData, - nonce: number, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - connection, - ).methods.attestToken(nonce); - - console.log( - getAttestTokenAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - mint, - message, - ), - ); - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getAttestTokenAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - mint, - message, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface AttestTokenAccounts { - payer: PublicKey; - config: PublicKey; - mint: PublicKey; - wrappedMeta: PublicKey; - splMetadata: PublicKey; - wormholeBridge: PublicKey; - wormholeMessage: PublicKey; - wormholeEmitter: PublicKey; - wormholeSequence: PublicKey; - wormholeFeeCollector: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - wormholeProgram: PublicKey; -} - -export function getAttestTokenAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - mint: PublicKeyInitData, - message: PublicKeyInitData, -): AttestTokenAccounts { - const { - bridge: wormholeBridge, - emitter: wormholeEmitter, - sequence: wormholeSequence, - feeCollector: wormholeFeeCollector, - clock, - rent, - systemProgram, - } = coreUtils.getPostMessageAccounts( - wormholeProgramId, - payer, - message, - tokenBridgeProgramId, - ); - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - mint: new PublicKey(mint), - wrappedMeta: deriveWrappedMetaKey(tokenBridgeProgramId, mint), - splMetadata: deriveSplTokenMetadataKey(mint), - wormholeBridge, - wormholeMessage: new PublicKey(message), - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - rent, - systemProgram, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/completeNative.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/completeNative.ts deleted file mode 100644 index c82a5e426..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/completeNative.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from '@solana/web3.js'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; -import { utils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveEndpointKey, - deriveTokenBridgeConfigKey, - deriveCustodyKey, - deriveCustodySignerKey, -} from './../accounts/index.js'; -import type { TokenBridge } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; - -export function createCompleteTransferNativeInstruction( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: TokenBridge.TransferVAA, - feeRecipient?: PublicKeyInitData, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - connection, - ).methods.completeNative(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getCompleteTransferNativeAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - vaa, - feeRecipient, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface CompleteTransferNativeAccounts { - payer: PublicKey; - config: PublicKey; - vaa: PublicKey; - claim: PublicKey; - endpoint: PublicKey; - to: PublicKey; - toFees: PublicKey; - custody: PublicKey; - mint: PublicKey; - custodySigner: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -export function getCompleteTransferNativeAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: TokenBridge.TransferVAA, - feeRecipient?: PublicKeyInitData, -): CompleteTransferNativeAccounts { - const mint = new PublicKey(vaa.payload.token.address.toUint8Array()); - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - vaa: utils.derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: utils.deriveClaimKey( - tokenBridgeProgramId, - vaa.emitterAddress.toUint8Array(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - endpoint: deriveEndpointKey( - tokenBridgeProgramId, - toChainId(vaa.emitterChain), - vaa.emitterAddress.toUint8Array(), - ), - to: new PublicKey(vaa.payload.to.address.toUint8Array()), - toFees: new PublicKey( - feeRecipient === undefined - ? vaa.payload.to.address.toUint8Array() - : feeRecipient, - ), - custody: deriveCustodyKey(tokenBridgeProgramId, mint), - mint, - custodySigner: deriveCustodySignerKey(tokenBridgeProgramId), - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/completeWrapped.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/completeWrapped.ts deleted file mode 100644 index 441ac1235..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/completeWrapped.ts +++ /dev/null @@ -1,107 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from '@solana/web3.js'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; -import { utils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveEndpointKey, - deriveTokenBridgeConfigKey, - deriveWrappedMintKey, - deriveWrappedMetaKey, - deriveMintAuthorityKey, -} from './../accounts/index.js'; -import type { TokenBridge } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; - -export function createCompleteTransferWrappedInstruction( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: TokenBridge.TransferVAA, - feeRecipient?: PublicKeyInitData, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - connection, - ).methods.completeWrapped(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getCompleteTransferWrappedAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - vaa, - feeRecipient, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface CompleteTransferWrappedAccounts { - payer: PublicKey; - config: PublicKey; - vaa: PublicKey; - claim: PublicKey; - endpoint: PublicKey; - to: PublicKey; - toFees: PublicKey; - mint: PublicKey; - wrappedMeta: PublicKey; - mintAuthority: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -export function getCompleteTransferWrappedAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: TokenBridge.TransferVAA, - feeRecipient?: PublicKeyInitData, -): CompleteTransferWrappedAccounts { - const mint = deriveWrappedMintKey( - tokenBridgeProgramId, - toChainId(vaa.payload.token.chain), - vaa.payload.token.address.toUint8Array(), - ); - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - vaa: utils.derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: utils.deriveClaimKey( - tokenBridgeProgramId, - vaa.emitterAddress.toUint8Array(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - endpoint: deriveEndpointKey( - tokenBridgeProgramId, - toChainId(vaa.emitterChain), - vaa.emitterAddress.toUint8Array(), - ), - to: new PublicKey(vaa.payload.to.address.toUint8Array()), - toFees: new PublicKey( - feeRecipient === undefined - ? vaa.payload.to.address.toUint8Array() - : feeRecipient, - ), - mint, - wrappedMeta: deriveWrappedMetaKey(tokenBridgeProgramId, mint), - mintAuthority: deriveMintAuthorityKey(tokenBridgeProgramId), - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/createWrapped.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/createWrapped.ts deleted file mode 100644 index fb2c44001..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/createWrapped.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from '@solana/web3.js'; -import type { TokenBridge } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; -import { utils as CoreUtils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveSplTokenMetadataKey, - SplTokenMetadataProgram, -} from '../../splMetadata.js'; -import { - deriveEndpointKey, - deriveMintAuthorityKey, - deriveTokenBridgeConfigKey, - deriveWrappedMetaKey, - deriveWrappedMintKey, -} from './../accounts/index.js'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; - -export function createCreateWrappedInstruction( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: TokenBridge.AttestVAA, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - connection, - ).methods.createWrapped(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getCreateWrappedAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - vaa, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface CreateWrappedAccounts { - payer: PublicKey; - config: PublicKey; - endpoint: PublicKey; - vaa: PublicKey; - claim: PublicKey; - mint: PublicKey; - wrappedMeta: PublicKey; - splMetadata: PublicKey; - mintAuthority: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - splMetadataProgram: PublicKey; - wormholeProgram: PublicKey; -} - -export function getCreateWrappedAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: TokenBridge.VAA, -): CreateWrappedAccounts { - const mint = deriveWrappedMintKey( - tokenBridgeProgramId, - toChainId(vaa.payload.token.chain), - vaa.payload.token.address.toUint8Array(), - ); - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - endpoint: deriveEndpointKey( - tokenBridgeProgramId, - toChainId(vaa.emitterChain), - vaa.emitterAddress.toUint8Array(), - ), - vaa: CoreUtils.derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: CoreUtils.deriveClaimKey( - tokenBridgeProgramId, - vaa.emitterAddress.toUint8Array(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - mint, - wrappedMeta: deriveWrappedMetaKey(tokenBridgeProgramId, mint), - splMetadata: deriveSplTokenMetadataKey(mint), - mintAuthority: deriveMintAuthorityKey(tokenBridgeProgramId), - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, - splMetadataProgram: SplTokenMetadataProgram.programId, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/governance.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/governance.ts deleted file mode 100644 index 050288665..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/governance.ts +++ /dev/null @@ -1,154 +0,0 @@ -import type { - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { - PublicKey, - SystemProgram, - SYSVAR_CLOCK_PUBKEY, - SYSVAR_RENT_PUBKEY, -} from '@solana/web3.js'; -import type { VAA } from '@wormhole-foundation/sdk-connect'; -import { toChainId } from '@wormhole-foundation/sdk-connect'; -import { utils } from '@wormhole-foundation/sdk-solana'; -import { utils as CoreUtils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveEndpointKey, - deriveTokenBridgeConfigKey, -} from './../accounts/index.js'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; - -export function createRegisterChainInstruction( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'TokenBridge:RegisterChain'>, -): TransactionInstruction { - const methods = - createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - ).methods.registerChain(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getRegisterChainAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - vaa, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface RegisterChainAccounts { - payer: PublicKey; - config: PublicKey; - endpoint: PublicKey; - vaa: PublicKey; - claim: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - wormholeProgram: PublicKey; -} - -export function getRegisterChainAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'TokenBridge:RegisterChain'>, -): RegisterChainAccounts { - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - endpoint: deriveEndpointKey( - tokenBridgeProgramId, - toChainId(vaa.payload.actionArgs.foreignChain), - vaa.payload.actionArgs.foreignAddress.toUint8Array(), - ), - vaa: CoreUtils.derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: CoreUtils.deriveClaimKey( - tokenBridgeProgramId, - vaa.emitterAddress.toUint8Array(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} - -export function createUpgradeContractInstruction( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'TokenBridge:UpgradeContract'>, - spill?: PublicKeyInitData, -): TransactionInstruction { - const methods = - createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - ).methods.upgradeContract(); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getUpgradeContractAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - vaa, - spill, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface UpgradeContractAccounts { - payer: PublicKey; - vaa: PublicKey; - claim: PublicKey; - upgradeAuthority: PublicKey; - spill: PublicKey; - implementation: PublicKey; - programData: PublicKey; - tokenBridgeProgram: PublicKey; - rent: PublicKey; - clock: PublicKey; - bpfLoaderUpgradeable: PublicKey; - systemProgram: PublicKey; -} - -export function getUpgradeContractAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - vaa: VAA<'TokenBridge:UpgradeContract'>, - spill?: PublicKeyInitData, -): UpgradeContractAccounts { - return { - payer: new PublicKey(payer), - vaa: CoreUtils.derivePostedVaaKey(wormholeProgramId, Buffer.from(vaa.hash)), - claim: CoreUtils.deriveClaimKey( - tokenBridgeProgramId, - vaa.emitterAddress.toUint8Array(), - toChainId(vaa.emitterChain), - vaa.sequence, - ), - upgradeAuthority: CoreUtils.deriveUpgradeAuthorityKey(tokenBridgeProgramId), - spill: new PublicKey(spill === undefined ? payer : spill), - implementation: new PublicKey(vaa.payload.actionArgs.newContract), - programData: utils.deriveProgramDataAddress(tokenBridgeProgramId), - tokenBridgeProgram: new PublicKey(tokenBridgeProgramId), - rent: SYSVAR_RENT_PUBKEY, - clock: SYSVAR_CLOCK_PUBKEY, - bpfLoaderUpgradeable: utils.BPF_LOADER_UPGRADEABLE_PROGRAM_ID, - systemProgram: SystemProgram.programId, - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/index.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/index.ts deleted file mode 100644 index 14fd27425..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export * from './approve.js'; -export * from './attestToken.js'; -export * from './completeNative.js'; -export * from './completeWrapped.js'; -export * from './createWrapped.js'; -export * from './initialize.js'; -export * from './governance.js'; -export * from './transferNative.js'; -export * from './transferNativeWithPayload.js'; -export * from './transferWrapped.js'; -export * from './transferWrappedWithPayload.js'; diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/initialize.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/initialize.ts deleted file mode 100644 index ba1d582ee..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/initialize.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from '@solana/web3.js'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; -import { deriveTokenBridgeConfigKey } from './../accounts/index.js'; - -export function createInitializeInstruction( - tokenBridgeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - ).methods.initialize(wormholeProgramId as any); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getInitializeAccounts(tokenBridgeProgramId, payer) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface InitializeAccounts { - payer: PublicKey; - config: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; -} - -export function getInitializeAccounts( - tokenBridgeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, -): InitializeAccounts { - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - rent: SYSVAR_RENT_PUBKEY, - systemProgram: SystemProgram.programId, - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferNative.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferNative.ts deleted file mode 100644 index 8cbd3ab26..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferNative.ts +++ /dev/null @@ -1,121 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; -import { utils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveAuthoritySignerKey, - deriveCustodySignerKey, - deriveTokenBridgeConfigKey, - deriveCustodyKey, -} from './../accounts/index.js'; - -export function createTransferNativeInstruction( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - from: PublicKeyInitData, - mint: PublicKeyInitData, - nonce: number, - amount: bigint, - fee: bigint, - targetAddress: Buffer | Uint8Array, - targetChain: number, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - connection, - ).methods.transferNative( - nonce, - amount as any, - fee as any, - Buffer.from(targetAddress) as any, - targetChain, - ); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getTransferNativeAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - from, - mint, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface TransferNativeAccounts { - payer: PublicKey; - config: PublicKey; - from: PublicKey; - mint: PublicKey; - custody: PublicKey; - authoritySigner: PublicKey; - custodySigner: PublicKey; - wormholeBridge: PublicKey; - wormholeMessage: PublicKey; - wormholeEmitter: PublicKey; - wormholeSequence: PublicKey; - wormholeFeeCollector: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -export function getTransferNativeAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - from: PublicKeyInitData, - mint: PublicKeyInitData, -): TransferNativeAccounts { - const { - wormholeBridge, - wormholeMessage, - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - rent, - systemProgram, - } = utils.getPostMessageCpiAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - ); - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - from: new PublicKey(from), - mint: new PublicKey(mint), - custody: deriveCustodyKey(tokenBridgeProgramId, mint), - authoritySigner: deriveAuthoritySignerKey(tokenBridgeProgramId), - custodySigner: deriveCustodySignerKey(tokenBridgeProgramId), - wormholeBridge, - wormholeMessage: wormholeMessage, - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - rent, - systemProgram, - tokenProgram: TOKEN_PROGRAM_ID, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferNativeWithPayload.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferNativeWithPayload.ts deleted file mode 100644 index a291cf8ab..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferNativeWithPayload.ts +++ /dev/null @@ -1,128 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; -import { utils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveAuthoritySignerKey, - deriveCustodySignerKey, - deriveTokenBridgeConfigKey, - deriveCustodyKey, - deriveSenderAccountKey, -} from './../accounts/index.js'; - -export function createTransferNativeWithPayloadInstruction( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - from: PublicKeyInitData, - mint: PublicKeyInitData, - nonce: number, - amount: bigint, - targetAddress: Buffer | Uint8Array, - targetChain: number, - payload: Buffer | Uint8Array, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - connection, - ).methods.transferNativeWithPayload( - nonce, - amount as any, - Buffer.from(targetAddress) as any, - targetChain, - Buffer.from(payload) as any, - null, - ); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getTransferNativeWithPayloadAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - from, - mint, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface TransferNativeWithPayloadAccounts { - payer: PublicKey; - config: PublicKey; - from: PublicKey; - mint: PublicKey; - custody: PublicKey; - authoritySigner: PublicKey; - custodySigner: PublicKey; - wormholeBridge: PublicKey; - wormholeMessage: PublicKey; - wormholeEmitter: PublicKey; - wormholeSequence: PublicKey; - wormholeFeeCollector: PublicKey; - clock: PublicKey; - sender: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -export function getTransferNativeWithPayloadAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - from: PublicKeyInitData, - mint: PublicKeyInitData, - cpiProgramId?: PublicKeyInitData, -): TransferNativeWithPayloadAccounts { - const { - wormholeBridge, - wormholeMessage, - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - rent, - systemProgram, - } = utils.getPostMessageCpiAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - ); - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - from: new PublicKey(from), - mint: new PublicKey(mint), - custody: deriveCustodyKey(tokenBridgeProgramId, mint), - authoritySigner: deriveAuthoritySignerKey(tokenBridgeProgramId), - custodySigner: deriveCustodySignerKey(tokenBridgeProgramId), - wormholeBridge, - wormholeMessage: wormholeMessage, - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - sender: new PublicKey( - cpiProgramId === undefined ? payer : deriveSenderAccountKey(cpiProgramId), - ), - rent, - systemProgram, - tokenProgram: TOKEN_PROGRAM_ID, - wormholeProgram: new PublicKey(wormholeProgramId), - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferWrapped.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferWrapped.ts deleted file mode 100644 index d4833f6b2..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferWrapped.ts +++ /dev/null @@ -1,132 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; -import { utils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveAuthoritySignerKey, - deriveTokenBridgeConfigKey, - deriveWrappedMetaKey, - deriveWrappedMintKey, -} from './../accounts/index.js'; - -export function createTransferWrappedInstruction( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - from: PublicKeyInitData, - fromOwner: PublicKeyInitData, - tokenChain: number, - tokenAddress: Buffer | Uint8Array, - nonce: number, - amount: bigint, - fee: bigint, - targetAddress: Buffer | Uint8Array, - targetChain: number, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - connection, - ).methods.transferWrapped( - nonce, - amount as any, - fee as any, - Buffer.from(targetAddress) as any, - targetChain, - ); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getTransferWrappedAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - from, - fromOwner, - tokenChain, - tokenAddress, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface TransferWrappedAccounts { - payer: PublicKey; - config: PublicKey; - from: PublicKey; - fromOwner: PublicKey; - mint: PublicKey; - wrappedMeta: PublicKey; - authoritySigner: PublicKey; - wormholeBridge: PublicKey; - wormholeMessage: PublicKey; - wormholeEmitter: PublicKey; - wormholeSequence: PublicKey; - wormholeFeeCollector: PublicKey; - clock: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - wormholeProgram: PublicKey; - tokenProgram: PublicKey; -} - -export function getTransferWrappedAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - from: PublicKeyInitData, - fromOwner: PublicKeyInitData, - tokenChain: number, - tokenAddress: Buffer | Uint8Array, -): TransferWrappedAccounts { - const mint = deriveWrappedMintKey( - tokenBridgeProgramId, - tokenChain, - tokenAddress, - ); - const { - wormholeBridge, - wormholeMessage, - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - rent, - systemProgram, - } = utils.getPostMessageCpiAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - ); - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - from: new PublicKey(from), - fromOwner: new PublicKey(fromOwner), - mint: mint, - wrappedMeta: deriveWrappedMetaKey(tokenBridgeProgramId, mint), - authoritySigner: deriveAuthoritySignerKey(tokenBridgeProgramId), - wormholeBridge, - wormholeMessage: wormholeMessage, - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - rent, - systemProgram, - wormholeProgram: new PublicKey(wormholeProgramId), - tokenProgram: TOKEN_PROGRAM_ID, - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferWrappedWithPayload.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferWrappedWithPayload.ts deleted file mode 100644 index 5e87a3940..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/instructions/transferWrappedWithPayload.ts +++ /dev/null @@ -1,140 +0,0 @@ -import type { - Connection, - PublicKeyInitData, - TransactionInstruction, -} from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { createReadOnlyTokenBridgeProgramInterface } from '../program.js'; - -import { utils } from '@wormhole-foundation/sdk-solana-core'; -import { - deriveAuthoritySignerKey, - deriveSenderAccountKey, - deriveTokenBridgeConfigKey, - deriveWrappedMetaKey, - deriveWrappedMintKey, -} from './../accounts/index.js'; - -export function createTransferWrappedWithPayloadInstruction( - connection: Connection, - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - from: PublicKeyInitData, - fromOwner: PublicKeyInitData, - tokenChain: number, - tokenAddress: Buffer | Uint8Array, - nonce: number, - amount: bigint, - targetAddress: Buffer | Uint8Array, - targetChain: number, - payload: Buffer | Uint8Array, -): TransactionInstruction { - const methods = createReadOnlyTokenBridgeProgramInterface( - tokenBridgeProgramId, - connection, - ).methods.transferWrappedWithPayload( - nonce, - amount as any, - Buffer.from(targetAddress) as any, - targetChain, - Buffer.from(payload) as any, - null, - ); - - // @ts-ignore - return methods._ixFn(...methods._args, { - accounts: getTransferWrappedWithPayloadAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - from, - fromOwner, - tokenChain, - tokenAddress, - ) as any, - signers: undefined, - remainingAccounts: undefined, - preInstructions: undefined, - postInstructions: undefined, - }); -} - -export interface TransferWrappedWithPayloadAccounts { - payer: PublicKey; - config: PublicKey; - from: PublicKey; - fromOwner: PublicKey; - mint: PublicKey; - wrappedMeta: PublicKey; - authoritySigner: PublicKey; - wormholeBridge: PublicKey; - wormholeMessage: PublicKey; - wormholeEmitter: PublicKey; - wormholeSequence: PublicKey; - wormholeFeeCollector: PublicKey; - clock: PublicKey; - sender: PublicKey; - rent: PublicKey; - systemProgram: PublicKey; - tokenProgram: PublicKey; - wormholeProgram: PublicKey; -} - -export function getTransferWrappedWithPayloadAccounts( - tokenBridgeProgramId: PublicKeyInitData, - wormholeProgramId: PublicKeyInitData, - payer: PublicKeyInitData, - message: PublicKeyInitData, - from: PublicKeyInitData, - fromOwner: PublicKeyInitData, - tokenChain: number, - tokenAddress: Buffer | Uint8Array, - cpiProgramId?: PublicKeyInitData, -): TransferWrappedWithPayloadAccounts { - const mint = deriveWrappedMintKey( - tokenBridgeProgramId, - tokenChain, - tokenAddress, - ); - const { - wormholeBridge, - wormholeMessage, - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - rent, - systemProgram, - } = utils.getPostMessageCpiAccounts( - tokenBridgeProgramId, - wormholeProgramId, - payer, - message, - ); - return { - payer: new PublicKey(payer), - config: deriveTokenBridgeConfigKey(tokenBridgeProgramId), - from: new PublicKey(from), - fromOwner: new PublicKey(fromOwner), - mint: mint, - wrappedMeta: deriveWrappedMetaKey(tokenBridgeProgramId, mint), - authoritySigner: deriveAuthoritySignerKey(tokenBridgeProgramId), - wormholeBridge, - wormholeMessage: wormholeMessage, - wormholeEmitter, - wormholeSequence, - wormholeFeeCollector, - clock, - sender: new PublicKey( - cpiProgramId === undefined ? payer : deriveSenderAccountKey(cpiProgramId), - ), - rent, - systemProgram, - wormholeProgram: new PublicKey(wormholeProgramId), - tokenProgram: TOKEN_PROGRAM_ID, - }; -} diff --git a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/program.ts b/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/program.ts deleted file mode 100644 index 35ebb8627..000000000 --- a/platforms/solana/protocols/tokenBridge/src/utils/tokenBridge/program.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { Connection, PublicKeyInitData } from '@solana/web3.js'; -import { PublicKey } from '@solana/web3.js'; -import type { Provider } from '@coral-xyz/anchor'; -import { Program } from '@coral-xyz/anchor'; -import { utils } from '@wormhole-foundation/sdk-solana'; -import { TokenBridgeCoder } from './coder/index.js'; -import { - type TokenBridge, - TOKEN_BRIDGE_IDL as IDL, -} from '../../tokenBridgeType.js'; - -export function createTokenBridgeProgramInterface( - programId: PublicKeyInitData, - provider?: Provider, -): Program { - return new Program( - IDL as TokenBridge, - new PublicKey(programId), - provider === undefined ? ({ connection: null } as any) : provider, - coder(), - ); -} - -export function createReadOnlyTokenBridgeProgramInterface( - programId: PublicKeyInitData, - connection?: Connection, -): Program { - return createTokenBridgeProgramInterface( - programId, - utils.createReadOnlyProvider(connection), - ); -} - -export function coder(): TokenBridgeCoder { - return new TokenBridgeCoder(IDL as TokenBridge); -} diff --git a/platforms/solana/src/testing/client/token-bridge.ts b/platforms/solana/src/testing/client/token-bridge.ts index daeefc86d..f57b1144a 100644 --- a/platforms/solana/src/testing/client/token-bridge.ts +++ b/platforms/solana/src/testing/client/token-bridge.ts @@ -7,7 +7,7 @@ import { SystemProgram, SYSVAR_RENT_PUBKEY, } from '@solana/web3.js'; -import { Chain, layout, Network } from '@wormhole-foundation/sdk-base'; +import { Chain, Network, serializeLayout } from '@wormhole-foundation/sdk-base'; import { Contracts, UniversalAddress, @@ -69,7 +69,7 @@ export class TestingTokenBridge { endpoint: (chain: Chain, address: UniversalAddress) => { return this.findPda( - layout.serializeLayout( + serializeLayout( { ...layoutItems.chainItem(), endianness: 'big' }, chain, ), diff --git a/platforms/solana/src/testing/helper.ts b/platforms/solana/src/testing/helper.ts index c52e729c0..2475329cd 100644 --- a/platforms/solana/src/testing/helper.ts +++ b/platforms/solana/src/testing/helper.ts @@ -26,6 +26,7 @@ import { Network } from '@wormhole-foundation/sdk-base'; import { Contracts } from '@wormhole-foundation/sdk-definitions'; import { TestingWormholeCore } from './client/wormhole-core.js'; import { TestingTokenBridge } from './client/token-bridge.js'; +import { encoding } from '@wormhole-foundation/sdk-base'; const execAsync = promisify(exec); @@ -43,7 +44,7 @@ type Tuple = R['length'] extends N * const [keypair1, keypair2] = await h.airdrop(h.keypair.several(2)); * ``` */ -export class TestsHelper { +export class TestHelper { static readonly LOCALHOST = 'http://localhost:8899'; readonly connection: Connection; @@ -54,13 +55,13 @@ export class TestsHelper { > = {}; constructor(finality: Finality = 'confirmed') { - if (TestsHelper.connectionsCache[finality] === undefined) { - TestsHelper.connectionsCache[finality] = new Connection( - TestsHelper.LOCALHOST, + if (TestHelper.connectionsCache[finality] === undefined) { + TestHelper.connectionsCache[finality] = new Connection( + TestHelper.LOCALHOST, finality, ); } - this.connection = TestsHelper.connectionsCache[finality]; + this.connection = TestHelper.connectionsCache[finality]; this.finality = finality; } @@ -91,14 +92,14 @@ export class TestsHelper { universalAddress = { generate: (ethereum?: 'ethereum'): UniversalAddress => - ethereum === 'ethereum' - ? new UniversalAddress( - Buffer.concat([ - Buffer.alloc(12), - PublicKey.unique().toBuffer().subarray(12), - ]), - ) - : new UniversalAddress(PublicKey.unique().toBuffer()), + new UniversalAddress( + ethereum === 'ethereum' + ? encoding.bytes.concat( + new Uint8Array(12), + PublicKey.unique().toBytes().subarray(12), + ) + : PublicKey.unique().toBytes(), + ), several: ( amount: number, ethereum?: 'ethereum', @@ -186,7 +187,7 @@ export class TestsHelper { // Deploy: await execAsync( - `solana --url ${TestsHelper.LOCALHOST} -k ${authorityKeypair} program deploy ${binary} --program-id ${programKeypair}`, + `solana --url ${TestHelper.LOCALHOST} -k ${authorityKeypair} program deploy ${binary} --program-id ${programKeypair}`, ); // Wait for deploy to be finalized (otherwise there can be a problem where the