diff --git a/core/definitions/src/protocols/core.ts b/core/definitions/src/protocols/core.ts index f0723574b..7471793b4 100644 --- a/core/definitions/src/protocols/core.ts +++ b/core/definitions/src/protocols/core.ts @@ -10,6 +10,7 @@ export interface WormholeCore< P extends Platform, C extends PlatformToChains

, > { + getMessageFee(): Promise; publishMessage( sender: AccountAddress, message: string | Uint8Array, diff --git a/examples/src/messaging.ts b/examples/src/messaging.ts index 07ed2cabc..55ce98a94 100644 --- a/examples/src/messaging.ts +++ b/examples/src/messaging.ts @@ -1,14 +1,14 @@ import { Wormhole, encoding, signSendWait } from "@wormhole-foundation/connect-sdk"; -import { AlgorandPlatform } from "@wormhole-foundation/connect-sdk-algorand"; +import { SolanaPlatform } from "@wormhole-foundation/connect-sdk-solana"; import { getStuff } from "./helpers"; // register the protocol -import "@wormhole-foundation/connect-sdk-algorand-core"; +import "@wormhole-foundation/connect-sdk-solana-core"; (async function () { - const wh = new Wormhole("Testnet", [AlgorandPlatform]); + const wh = new Wormhole("Testnet", [SolanaPlatform]); - const chain = wh.getChain("Algorand"); + const chain = wh.getChain("Solana"); const { signer, address } = await getStuff(chain); // Get a reference to the core messaging bridge diff --git a/platforms/aptos/protocols/core/src/core.ts b/platforms/aptos/protocols/core/src/core.ts index c9013e8f8..700c81fd4 100644 --- a/platforms/aptos/protocols/core/src/core.ts +++ b/platforms/aptos/protocols/core/src/core.ts @@ -36,6 +36,9 @@ export class AptosWormholeCore throw new Error(`CoreBridge contract Address for chain ${chain} not found`); this.coreBridge = coreBridgeAddress; } + getMessageFee(): Promise { + throw new Error("Method not implemented."); + } static async fromRpc( connection: AptosClient, diff --git a/platforms/cosmwasm/protocols/core/src/wormholeCore.ts b/platforms/cosmwasm/protocols/core/src/core.ts similarity index 97% rename from platforms/cosmwasm/protocols/core/src/wormholeCore.ts rename to platforms/cosmwasm/protocols/core/src/core.ts index 3ca55fec5..3d2153f24 100644 --- a/platforms/cosmwasm/protocols/core/src/wormholeCore.ts +++ b/platforms/cosmwasm/protocols/core/src/core.ts @@ -37,6 +37,10 @@ export class CosmwasmWormholeCore this.coreAddress = coreAddress; } + getMessageFee(): Promise { + throw new Error("Method not implemented."); + } + static async fromRpc( rpc: CosmWasmClient, config: ChainsConfig, diff --git a/platforms/cosmwasm/protocols/core/src/index.ts b/platforms/cosmwasm/protocols/core/src/index.ts index 4ddb693ea..6e330d373 100644 --- a/platforms/cosmwasm/protocols/core/src/index.ts +++ b/platforms/cosmwasm/protocols/core/src/index.ts @@ -1,6 +1,6 @@ import { registerProtocol } from "@wormhole-foundation/connect-sdk"; import { _platform } from "@wormhole-foundation/connect-sdk-cosmwasm"; -import { CosmwasmWormholeCore } from "./wormholeCore"; +import { CosmwasmWormholeCore } from "./core"; declare global { namespace WormholeNamespace { @@ -12,4 +12,4 @@ declare global { registerProtocol(_platform, "WormholeCore", CosmwasmWormholeCore); -export * from "./wormholeCore"; +export * from "./core"; diff --git a/platforms/evm/protocols/core/src/wormholeCore.ts b/platforms/evm/protocols/core/src/core.ts similarity index 97% rename from platforms/evm/protocols/core/src/wormholeCore.ts rename to platforms/evm/protocols/core/src/core.ts index 74cb43e6a..9ada952fe 100644 --- a/platforms/evm/protocols/core/src/wormholeCore.ts +++ b/platforms/evm/protocols/core/src/core.ts @@ -62,6 +62,10 @@ export class EvmWormholeCore< ); } + async getMessageFee(): Promise { + return await this.core.messageFee.staticCall(); + } + static async fromRpc( provider: Provider, config: ChainsConfig, diff --git a/platforms/evm/protocols/core/src/index.ts b/platforms/evm/protocols/core/src/index.ts index 57bb0d8d8..887a2d3e8 100644 --- a/platforms/evm/protocols/core/src/index.ts +++ b/platforms/evm/protocols/core/src/index.ts @@ -1,6 +1,6 @@ import { registerProtocol } from '@wormhole-foundation/connect-sdk'; import { _platform } from '@wormhole-foundation/connect-sdk-evm'; -import { EvmWormholeCore } from './wormholeCore'; +import { EvmWormholeCore } from './core'; declare global { namespace WormholeNamespace { @@ -13,4 +13,4 @@ declare global { registerProtocol(_platform, 'WormholeCore', EvmWormholeCore); export * as ethers_contracts from './ethers-contracts'; -export * from './wormholeCore'; +export * from './core'; diff --git a/platforms/solana/protocols/core/src/core.ts b/platforms/solana/protocols/core/src/core.ts index abfc6f6da..1c7a21ee3 100644 --- a/platforms/solana/protocols/core/src/core.ts +++ b/platforms/solana/protocols/core/src/core.ts @@ -30,11 +30,14 @@ import { } from '@wormhole-foundation/connect-sdk'; import { Wormhole as WormholeCoreContract } from './types'; import { + BridgeData, + createBridgeFeeTransferInstruction, createPostMessageInstruction, createPostVaaInstruction, createReadOnlyWormholeProgramInterface, createVerifySignaturesInstructions, derivePostedVaaKey, + getWormholeBridgeData, } from './utils'; const SOLANA_SEQ_LOG = 'Program log: Sequence: '; @@ -45,6 +48,7 @@ export class SolanaWormholeCore readonly chainId: ChainId; readonly coreBridge: Program; readonly address: string; + protected bridgeData?: BridgeData; constructor( readonly network: N, @@ -86,6 +90,17 @@ export class SolanaWormholeCore ); } + async getMessageFee(): Promise { + // cache lookups since this should not change frequently + if (!this.bridgeData) + this.bridgeData = await getWormholeBridgeData( + this.connection, + this.coreBridge.programId, + ); + + return this.bridgeData.config.fee; + } + async *publishMessage( sender: AnySolanaAddress, message: Uint8Array, @@ -104,11 +119,18 @@ export class SolanaWormholeCore consistencyLevel, ); + const fee = await this.getMessageFee(); + const feeTransferIx = createBridgeFeeTransferInstruction( + this.coreBridge.programId, + payer, + fee, + ); + const { blockhash } = await SolanaPlatform.latestBlock(this.connection); const transaction = new Transaction(); transaction.recentBlockhash = blockhash; transaction.feePayer = payer; - transaction.add(postMsgIx); + transaction.add(feeTransferIx, postMsgIx); transaction.partialSign(messageAccount); yield this.createUnsignedTx(transaction, 'Core.PublishMessage'); diff --git a/platforms/solana/protocols/core/src/utils/instructions/feeTransfer.ts b/platforms/solana/protocols/core/src/utils/instructions/feeTransfer.ts index ae0945c7e..5257f5f15 100644 --- a/platforms/solana/protocols/core/src/utils/instructions/feeTransfer.ts +++ b/platforms/solana/protocols/core/src/utils/instructions/feeTransfer.ts @@ -1,24 +1,16 @@ import { - Commitment, - Connection, PublicKey, PublicKeyInitData, SystemProgram, TransactionInstruction, } from '@solana/web3.js'; -import { deriveFeeCollectorKey, getWormholeBridgeData } from '../accounts'; +import { deriveFeeCollectorKey } from '../accounts'; -export async function createBridgeFeeTransferInstruction( - connection: Connection, +export function createBridgeFeeTransferInstruction( wormholeProgramId: PublicKeyInitData, payer: PublicKeyInitData, - commitment?: Commitment, -): Promise { - const fee = await getWormholeBridgeData( - connection, - wormholeProgramId, - commitment, - ).then((data) => data.config.fee); + fee: bigint, +): TransactionInstruction { return SystemProgram.transfer({ fromPubkey: new PublicKey(payer), toPubkey: deriveFeeCollectorKey(wormholeProgramId), diff --git a/platforms/solana/protocols/tokenBridge/src/tokenBridge.ts b/platforms/solana/protocols/tokenBridge/src/tokenBridge.ts index e87638954..3605705bb 100644 --- a/platforms/solana/protocols/tokenBridge/src/tokenBridge.ts +++ b/platforms/solana/protocols/tokenBridge/src/tokenBridge.ts @@ -216,10 +216,11 @@ export class SolanaTokenBridge // TODO: createNonce().readUInt32LE(0); const nonce = 0; + const msgFee = await this.coreBridge.getMessageFee(); const transferIx = await coreUtils.createBridgeFeeTransferInstruction( - this.connection, this.coreBridge.address, senderAddress, + msgFee, ); const messageKey = Keypair.generate(); const attestIx = createAttestTokenInstruction(