Skip to content

Commit

Permalink
add fee transfer ix to message example
Browse files Browse the repository at this point in the history
  • Loading branch information
barnjamin committed Jan 3, 2024
1 parent 4511053 commit ebf10c2
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 26 deletions.
26 changes: 20 additions & 6 deletions platforms/solana/protocols/core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ import {
createPostVaaInstruction,
createReadOnlyWormholeProgramInterface,
createVerifySignaturesInstructions,
createBridgeFeeTransferInstruction,
derivePostedVaaKey,
getWormholeBridgeData,
BridgeData,
} from './utils';

const SOLANA_SEQ_LOG = 'Program log: Sequence: ';
Expand All @@ -46,6 +48,7 @@ export class SolanaWormholeCore<N extends Network, C extends SolanaChains>
readonly chainId: ChainId;
readonly coreBridge: Program<WormholeCoreContract>;
readonly address: string;
protected bridgeData?: BridgeData;

constructor(
readonly network: N,
Expand Down Expand Up @@ -79,6 +82,7 @@ export class SolanaWormholeCore<N extends Network, C extends SolanaChains>
throw new Error(
`Network mismatch for chain ${chain}: ${conf.network} != ${network}`,
);

return new SolanaWormholeCore(
network as N,
chain,
Expand All @@ -88,11 +92,14 @@ export class SolanaWormholeCore<N extends Network, C extends SolanaChains>
}

async getMessageFee(): Promise<bigint> {
const bd = await getWormholeBridgeData(
this.connection,
this.coreBridge.programId,
);
return bd.config.fee;
// 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(
Expand All @@ -113,11 +120,18 @@ export class SolanaWormholeCore<N extends Network, C extends SolanaChains>
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');
Expand Down
Original file line number Diff line number Diff line change
@@ -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<TransactionInstruction> {
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),
Expand Down
8 changes: 5 additions & 3 deletions platforms/solana/protocols/tokenBridge/src/tokenBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,13 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
// TODO: createNonce().readUInt32LE(0);
const nonce = 0;

const transferIx = await coreUtils.createBridgeFeeTransferInstruction(
this.connection,
const fee = await this.coreBridge.getMessageFee();
const transferIx = coreUtils.createBridgeFeeTransferInstruction(
this.coreBridge.address,
senderAddress,
payer,
fee,
);

const messageKey = Keypair.generate();
const attestIx = createAttestTokenInstruction(
this.connection,
Expand Down
11 changes: 6 additions & 5 deletions platforms/solana/src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,17 @@ export class SolanaPlatform<N extends Network> extends PlatformContext<
// recoverable. Currently handles:
// - Blockhash not found (blockhash too new for the node we submitted to)
// - Not enough bytes (storage account not seen yet)

private static async sendWithRetry(
rpc: Connection,
stxns: SignedTx,
stxn: SignedTx,
opts: SendOptions,
retries: number = 3,
): Promise<string> {
// Shouldnt get hit but just in case
if (!retries) throw new Error('Too many retries');

try {
const txid = await rpc.sendRawTransaction(stxns.tx, opts);
const txid = await rpc.sendRawTransaction(stxn, opts);
return txid;
} catch (e) {
retries -= 1;
Expand All @@ -195,7 +194,7 @@ export class SolanaPlatform<N extends Network> extends PlatformContext<

// Blockhash not found _yet_
if (emsg.includes('Blockhash not found'))
return this.sendWithRetry(rpc, stxns, opts, retries);
return this.sendWithRetry(rpc, stxn, opts, retries);

// Find the log message with the error details
const loggedErr = e.logs.find((log) =>
Expand All @@ -204,7 +203,9 @@ export class SolanaPlatform<N extends Network> extends PlatformContext<

// Probably caused by storage account not seen yet
if (loggedErr && loggedErr.includes('Not enough bytes'))
return this.sendWithRetry(rpc, stxns, opts, retries);
return this.sendWithRetry(rpc, stxn, opts, retries);

throw e;
}
}

Expand Down

0 comments on commit ebf10c2

Please sign in to comment.