Skip to content

Commit

Permalink
allow opts to be passed to sendWait on solana platform
Browse files Browse the repository at this point in the history
  • Loading branch information
barnjamin committed Jan 2, 2024
1 parent bfb7a61 commit 0744d50
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 37 deletions.
5 changes: 2 additions & 3 deletions examples/src/tokenBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import "@wormhole-foundation/connect-sdk-algorand-tokenbridge";
const rcvChain = wh.getChain("Solana");

// Shortcut to allow transferring native gas token
//const token: TokenId | "native" = "native";
const token: TokenId | "native" = "native";

// A TokenId is just a `{chain, address}` pair and an alias for ChainAddress
// The `address` field must be a parsed address.
Expand All @@ -42,9 +42,8 @@ import "@wormhole-foundation/connect-sdk-algorand-tokenbridge";
// e.g.
// wAvax on Solana
// const token = Wormhole.chainAddress("Solana", "3Ftc5hTz9sG4huk79onufGiebJNDMZNL8HYgdMJ9E7JR");

// wSol on Avax
const token = Wormhole.chainAddress("Avalanche", "0xb10563644a6AB8948ee6d7f5b0a1fb15AaEa1E03");
// const token = Wormhole.chainAddress("Avalanche", "0xb10563644a6AB8948ee6d7f5b0a1fb15AaEa1E03");

// Normalized given token decimals later but can just pass bigints as base units
// Note: The Token bridge will dedust past 8 decimals
Expand Down
13 changes: 7 additions & 6 deletions platforms/solana/protocols/tokenBridge/src/tokenBridge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
Platform,
Chain,
ChainAddress,
ChainId,
Expand Down Expand Up @@ -49,7 +50,6 @@ import {
TransactionInstruction,
} from '@solana/web3.js';

import { Platform } from '@wormhole-foundation/sdk-base/src';
import { TokenBridge as TokenBridgeContract } from './tokenBridgeType';
import {
createApproveAuthoritySignerInstruction,
Expand Down Expand Up @@ -210,6 +210,8 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
payer?: AnySolanaAddress,
): AsyncGenerator<SolanaUnsignedTransaction<N, C>> {
if (!payer) throw new Error('Payer required to create attestation');

const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
const senderAddress = new SolanaAddress(payer).unwrap();
// TODO: createNonce().readUInt32LE(0);
const nonce = 0;
Expand All @@ -231,7 +233,6 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
);

const transaction = new Transaction().add(transferIx, attestIx);
const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
transaction.recentBlockhash = blockhash;
transaction.feePayer = senderAddress;
transaction.partialSign(messageKey);
Expand All @@ -244,9 +245,9 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
payer?: AnySolanaAddress,
): AsyncGenerator<SolanaUnsignedTransaction<N, C>> {
if (!payer) throw new Error('Payer required to create attestation');
const senderAddress = new SolanaAddress(payer).unwrap();

const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
const senderAddress = new SolanaAddress(payer).unwrap();

// Yield transactions to verify sigs and post the VAA
yield* this.coreBridge.postVaa(senderAddress, vaa, blockhash);
Expand Down Expand Up @@ -275,7 +276,9 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
): Promise<SolanaUnsignedTransaction<N, C>> {
// https://github.com/wormhole-foundation/wormhole-connect/blob/development/sdk/src/contexts/solana/context.ts#L245

const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
const senderAddress = new SolanaAddress(sender).unwrap();

// TODO: the payer can actually be different from the sender. We need to allow the user to pass in an optional payer
const payerPublicKey = senderAddress;

Expand Down Expand Up @@ -362,7 +365,6 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
payerPublicKey, //authority
);

const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
const transaction = new Transaction();
transaction.recentBlockhash = blockhash;
transaction.feePayer = payerPublicKey;
Expand Down Expand Up @@ -393,8 +395,8 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
return;
}

const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
const tokenAddress = new SolanaAddress(token).unwrap();

const senderAddress = new SolanaAddress(sender).unwrap();
const senderTokenAddress = await getAssociatedTokenAddress(
tokenAddress,
Expand Down Expand Up @@ -493,7 +495,6 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
tokenBridgeTransferIx,
);

const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
transaction.recentBlockhash = blockhash;
transaction.feePayer = senderAddress;
transaction.partialSign(message);
Expand Down
27 changes: 17 additions & 10 deletions platforms/solana/src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import { SolanaChain } from './chain';

import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
import {
BlockheightBasedTransactionConfirmationStrategy,
Commitment,
Connection,
ParsedAccountData,
PublicKey,
SendOptions,
} from '@solana/web3.js';
import { SolanaAddress, SolanaZeroAddress } from './address';
import {
Expand Down Expand Up @@ -164,23 +164,30 @@ export class SolanaPlatform<N extends Network> extends PlatformContext<
chain: Chain,
rpc: Connection,
stxns: SignedTx[],
opts?: SendOptions,
): Promise<TxHash[]> {
const { blockhash, lastValidBlockHeight } = await this.latestBlock(rpc);

// Set the commitment level to match the rpc commitment level
// otherwise, it defaults to finalized
if (!opts) opts = { preflightCommitment: rpc.commitment };

const txhashes = await Promise.all(
stxns.map((stxn) => {
return rpc.sendRawTransaction(stxn);
return rpc.sendRawTransaction(stxn, opts);
}),
);

await Promise.all(
txhashes.map((txid) => {
const bhs: BlockheightBasedTransactionConfirmationStrategy = {
signature: txid,
blockhash,
lastValidBlockHeight,
};
return rpc.confirmTransaction(bhs, rpc.commitment);
txhashes.map((signature) => {
return rpc.confirmTransaction(
{
signature,
blockhash,
lastValidBlockHeight,
},
rpc.commitment,
);
}),
);

Expand All @@ -191,7 +198,7 @@ export class SolanaPlatform<N extends Network> extends PlatformContext<
rpc: Connection,
commitment?: Commitment,
): Promise<{ blockhash: string; lastValidBlockHeight: number }> {
return rpc.getLatestBlockhash(commitment ?? rpc.commitment);
return rpc.getLatestBlockhash(commitment ?? 'finalized');
}

static async getLatestBlock(rpc: Connection): Promise<number> {
Expand Down
35 changes: 17 additions & 18 deletions platforms/solana/src/testing/sendSigner.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Connection, Keypair, Transaction } from '@solana/web3.js';
import { Connection, Keypair } from '@solana/web3.js';
import {
SignAndSendSigner,
UnsignedTransaction,
Expand Down Expand Up @@ -29,10 +29,10 @@ export class SolanaSendSigner<
}

async signAndSend(tx: UnsignedTransaction[]): Promise<any[]> {
const txids: string[] = [];

const { blockhash, lastValidBlockHeight } =
await SolanaPlatform.latestBlock(this._rpc);
await SolanaPlatform.latestBlock(this._rpc, 'finalized');

const txPromises: Promise<string>[] = [];

for (const txn of tx) {
const { description, transaction } = txn as SolanaUnsignedTransaction<
Expand All @@ -42,10 +42,9 @@ export class SolanaSendSigner<
console.log(`Signing: ${description} for ${this.address()}`);

if (this._debug) {
const st = transaction as Transaction;
console.log(st.signatures);
console.log(st.feePayer);
st.instructions.forEach((ix) => {
console.log(transaction.signatures);
console.log(transaction.feePayer);
transaction.instructions.forEach((ix) => {
console.log('Program', ix.programId.toBase58());
console.log('Data: ', ix.data.toString('hex'));
console.log(
Expand All @@ -57,21 +56,21 @@ export class SolanaSendSigner<

transaction.partialSign(this._keypair);

const txid = await this._rpc.sendRawTransaction(transaction.serialize(), {
// skipPreflight: true,
// preflightCommitment: this._rpc.commitment,
maxRetries: 5,
});

console.log(`Sent: ${description} for ${this.address()}`);
txPromises.push(
this._rpc.sendRawTransaction(transaction.serialize(), {
preflightCommitment: this._rpc.commitment,
}),
);
}
const txids = await Promise.all(txPromises);

// Wait for finalization
for (const signature of txids) {
await this._rpc.confirmTransaction({
signature: txid,
signature,
blockhash,
lastValidBlockHeight,
});

txids.push(txid);
}

return txids;
Expand Down

0 comments on commit 0744d50

Please sign in to comment.