Skip to content

Commit 99d540e

Browse files
committed
update solana to pass back all signers involved and require the sol signer set the recent blockhash
1 parent ebf10c2 commit 99d540e

File tree

10 files changed

+199
-181
lines changed

10 files changed

+199
-181
lines changed

platforms/solana/protocols/cctp/src/circleBridge.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
SolanaChains,
1919
SolanaPlatform,
2020
SolanaPlatformType,
21+
SolanaTransaction,
2122
SolanaUnsignedTransaction,
2223
} from '@wormhole-foundation/connect-sdk-solana';
2324
import { MessageTransmitter, TokenMessenger } from '.';
@@ -105,13 +106,10 @@ export class SolanaCircleBridge<N extends Network, C extends SolanaChains>
105106
senderPk,
106107
);
107108

108-
const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
109109
const transaction = new Transaction();
110-
transaction.recentBlockhash = blockhash;
111110
transaction.feePayer = senderPk;
112111
transaction.add(ix);
113-
114-
yield this.createUnsignedTx(transaction, 'CircleBridge.Redeem');
112+
yield this.createUnsignedTx({ transaction }, 'CircleBridge.Redeem');
115113
}
116114

117115
async *transfer(
@@ -140,13 +138,11 @@ export class SolanaCircleBridge<N extends Network, C extends SolanaChains>
140138
amount,
141139
);
142140

143-
const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
144141
const transaction = new Transaction();
145-
transaction.recentBlockhash = blockhash;
146142
transaction.feePayer = senderPk;
147143
transaction.add(ix);
148144

149-
yield this.createUnsignedTx(transaction, 'CircleBridge.Transfer');
145+
yield this.createUnsignedTx({ transaction }, 'CircleBridge.Transfer');
150146
}
151147

152148
async isTransferCompleted(message: CircleBridge.Message): Promise<boolean> {
@@ -216,7 +212,7 @@ export class SolanaCircleBridge<N extends Network, C extends SolanaChains>
216212
}
217213

218214
private createUnsignedTx(
219-
txReq: Transaction,
215+
txReq: SolanaTransaction,
220216
description: string,
221217
parallelizable: boolean = false,
222218
): SolanaUnsignedTransaction<N, C> {

platforms/solana/protocols/core/src/core.ts

+13-16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
SolanaPlatform,
1616
SolanaPlatformType,
1717
SolanaUnsignedTransaction,
18+
SolanaTransaction,
1819
} from '@wormhole-foundation/connect-sdk-solana';
1920
import {
2021
ChainId,
@@ -127,24 +128,20 @@ export class SolanaWormholeCore<N extends Network, C extends SolanaChains>
127128
fee,
128129
);
129130

130-
const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
131131
const transaction = new Transaction();
132-
transaction.recentBlockhash = blockhash;
133132
transaction.feePayer = payer;
134133
transaction.add(feeTransferIx, postMsgIx);
135-
transaction.partialSign(messageAccount);
136-
137-
yield this.createUnsignedTx(transaction, 'Core.PublishMessage');
134+
yield this.createUnsignedTx(
135+
{ transaction, signers: [messageAccount] },
136+
'Core.PublishMessage',
137+
);
138138
}
139139

140140
async *verifyMessage(sender: AnySolanaAddress, vaa: VAA) {
141141
yield* this.postVaa(sender, vaa);
142142
}
143143

144-
async *postVaa(sender: AnySolanaAddress, vaa: VAA, blockhash?: string) {
145-
if (!blockhash)
146-
({ blockhash } = await SolanaPlatform.latestBlock(this.connection));
147-
144+
async *postVaa(sender: AnySolanaAddress, vaa: VAA) {
148145
const postedVaaAddress = derivePostedVaaKey(
149146
this.coreBridge.programId,
150147
Buffer.from(vaa.hash),
@@ -171,11 +168,12 @@ export class SolanaWormholeCore<N extends Network, C extends SolanaChains>
171168
const verifySigTx = new Transaction().add(
172169
...verifySignaturesInstructions.slice(i, i + 2),
173170
);
174-
verifySigTx.recentBlockhash = blockhash;
175171
verifySigTx.feePayer = senderAddr;
176-
verifySigTx.partialSign(signatureSet);
177-
178-
yield this.createUnsignedTx(verifySigTx, 'Core.VerifySignature', true);
172+
yield this.createUnsignedTx(
173+
{ transaction: verifySigTx, signers: [signatureSet] },
174+
'Core.VerifySignature',
175+
true,
176+
);
179177
}
180178

181179
// Finally create the VAA posting transaction
@@ -188,10 +186,9 @@ export class SolanaWormholeCore<N extends Network, C extends SolanaChains>
188186
signatureSet.publicKey,
189187
),
190188
);
191-
postVaaTx.recentBlockhash = blockhash;
192189
postVaaTx.feePayer = senderAddr;
193190

194-
yield this.createUnsignedTx(postVaaTx, 'Core.PostVAA');
191+
yield this.createUnsignedTx({ transaction: postVaaTx }, 'Core.PostVAA');
195192
}
196193

197194
static parseSequenceFromLog(
@@ -328,7 +325,7 @@ export class SolanaWormholeCore<N extends Network, C extends SolanaChains>
328325
}
329326

330327
private createUnsignedTx(
331-
txReq: Transaction,
328+
txReq: SolanaTransaction,
332329
description: string,
333330
parallelizable: boolean = false,
334331
): SolanaUnsignedTransaction<N, C> {

platforms/solana/protocols/tokenBridge/src/automaticTokenBridge.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
SolanaChains,
1717
SolanaPlatform,
1818
SolanaPlatformType,
19+
SolanaTransaction,
1920
SolanaUnsignedTransaction,
2021
} from '@wormhole-foundation/connect-sdk-solana';
2122

@@ -173,18 +174,18 @@ export class SolanaAutomaticTokenBridge<
173174
nonce,
174175
);
175176

176-
const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
177-
178177
transaction.add(transferIx);
179-
transaction.recentBlockhash = blockhash;
180178
transaction.feePayer = senderAddress;
181179

182-
yield this.createUnsignedTx(transaction, 'AutomaticTokenBridge.Transfer');
180+
yield this.createUnsignedTx(
181+
{ transaction },
182+
'AutomaticTokenBridge.Transfer',
183+
);
183184
}
184185

185186
async *redeem(sender: AccountAddress<C>, vaa: AutomaticTokenBridge.VAA) {
186-
const redeemTx = new Transaction();
187-
yield this.createUnsignedTx(redeemTx, 'AutomaticTokenBridge.Redeem');
187+
const transaction = new Transaction();
188+
yield this.createUnsignedTx({ transaction }, 'AutomaticTokenBridge.Redeem');
188189
throw new Error('Method not implemented.');
189190
}
190191

@@ -327,7 +328,7 @@ export class SolanaAutomaticTokenBridge<
327328
}
328329

329330
private createUnsignedTx(
330-
txReq: Transaction,
331+
txReq: SolanaTransaction,
331332
description: string,
332333
parallelizable: boolean = false,
333334
): SolanaUnsignedTransaction<N, C> {

platforms/solana/protocols/tokenBridge/src/tokenBridge.ts

+28-41
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
SolanaChains,
2222
SolanaPlatform,
2323
SolanaPlatformType,
24+
SolanaTransaction,
2425
SolanaUnsignedTransaction,
2526
} from '@wormhole-foundation/connect-sdk-solana';
2627
import {
@@ -211,7 +212,6 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
211212
): AsyncGenerator<SolanaUnsignedTransaction<N, C>> {
212213
if (!payer) throw new Error('Payer required to create attestation');
213214

214-
const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
215215
const senderAddress = new SolanaAddress(payer).unwrap();
216216
// TODO: createNonce().readUInt32LE(0);
217217
const nonce = 0;
@@ -235,11 +235,11 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
235235
);
236236

237237
const transaction = new Transaction().add(transferIx, attestIx);
238-
transaction.recentBlockhash = blockhash;
239238
transaction.feePayer = senderAddress;
240-
transaction.partialSign(messageKey);
241-
242-
yield this.createUnsignedTx(transaction, 'Solana.AttestToken');
239+
yield this.createUnsignedTx(
240+
{ transaction, signers: [messageKey] },
241+
'Solana.AttestToken',
242+
);
243243
}
244244

245245
async *submitAttestation(
@@ -248,11 +248,10 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
248248
): AsyncGenerator<SolanaUnsignedTransaction<N, C>> {
249249
if (!payer) throw new Error('Payer required to create attestation');
250250

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

254253
// Yield transactions to verify sigs and post the VAA
255-
yield* this.coreBridge.postVaa(senderAddress, vaa, blockhash);
254+
yield* this.coreBridge.postVaa(senderAddress, vaa);
256255

257256
// Now yield the transaction to actually create the token
258257
const transaction = new Transaction().add(
@@ -264,10 +263,9 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
264263
vaa,
265264
),
266265
);
267-
transaction.recentBlockhash = blockhash;
268266
transaction.feePayer = senderAddress;
269267

270-
yield this.createUnsignedTx(transaction, 'Solana.CreateWrapped');
268+
yield this.createUnsignedTx({ transaction }, 'Solana.CreateWrapped');
271269
}
272270

273271
private async transferSol(
@@ -278,7 +276,6 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
278276
): Promise<SolanaUnsignedTransaction<N, C>> {
279277
// https://github.com/wormhole-foundation/wormhole-connect/blob/development/sdk/src/contexts/solana/context.ts#L245
280278

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

284281
// TODO: the payer can actually be different from the sender. We need to allow the user to pass in an optional payer
@@ -368,7 +365,6 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
368365
);
369366

370367
const transaction = new Transaction();
371-
transaction.recentBlockhash = blockhash;
372368
transaction.feePayer = payerPublicKey;
373369
transaction.add(
374370
createAncillaryAccountIx,
@@ -378,9 +374,10 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
378374
tokenBridgeTransferIx,
379375
closeAccountIx,
380376
);
381-
transaction.partialSign(message, ancillaryKeypair);
382-
383-
return this.createUnsignedTx(transaction, 'TokenBridge.TransferNative');
377+
return this.createUnsignedTx(
378+
{ transaction, signers: [message, ancillaryKeypair] },
379+
'TokenBridge.TransferNative',
380+
);
384381
}
385382

386383
async *transfer(
@@ -397,7 +394,6 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
397394
return;
398395
}
399396

400-
const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
401397
const tokenAddress = new SolanaAddress(token).unwrap();
402398
const senderAddress = new SolanaAddress(sender).unwrap();
403399
const senderTokenAddress = await getAssociatedTokenAddress(
@@ -497,17 +493,16 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
497493
tokenBridgeTransferIx,
498494
);
499495

500-
transaction.recentBlockhash = blockhash;
501496
transaction.feePayer = senderAddress;
502-
transaction.partialSign(message);
503-
504-
yield this.createUnsignedTx(transaction, 'TokenBridge.TransferTokens');
497+
yield this.createUnsignedTx(
498+
{ transaction, signers: [message] },
499+
'TokenBridge.TransferTokens',
500+
);
505501
}
506502

507503
private async *redeemAndUnwrap(
508504
sender: AnySolanaAddress,
509505
vaa: TokenBridge.TransferVAA,
510-
blockhash: string,
511506
) {
512507
// sender, fee payer
513508
const payerPublicKey = new SolanaAddress(sender).unwrap();
@@ -566,7 +561,6 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
566561
);
567562

568563
const transaction = new Transaction();
569-
transaction.recentBlockhash = blockhash;
570564
transaction.feePayer = payerPublicKey;
571565
transaction.add(
572566
completeTransferIx,
@@ -575,15 +569,13 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
575569
balanceTransferIx,
576570
closeAccountIx,
577571
);
578-
transaction.partialSign(ancillaryKeypair);
579-
yield this.createUnsignedTx(transaction, 'TokenBridge.RedeemAndUnwrap');
572+
yield this.createUnsignedTx(
573+
{ transaction, signers: [ancillaryKeypair] },
574+
'TokenBridge.RedeemAndUnwrap',
575+
);
580576
}
581577

582-
private async *createAta(
583-
sender: AnySolanaAddress,
584-
token: AnySolanaAddress,
585-
blockhash: string,
586-
) {
578+
private async *createAta(sender: AnySolanaAddress, token: AnySolanaAddress) {
587579
const senderAddress = new SolanaAddress(sender).unwrap();
588580
const tokenAddress = new SolanaAddress(token).unwrap();
589581

@@ -592,17 +584,16 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
592584
// If the ata doesn't exist yet, create it
593585
const acctInfo = await this.connection.getAccountInfo(ata);
594586
if (acctInfo === null) {
595-
const ataCreationTx = new Transaction().add(
587+
const transaction = new Transaction().add(
596588
createAssociatedTokenAccountInstruction(
597589
senderAddress,
598590
ata,
599591
senderAddress,
600592
tokenAddress,
601593
),
602594
);
603-
ataCreationTx.feePayer = senderAddress;
604-
ataCreationTx.recentBlockhash = blockhash;
605-
yield this.createUnsignedTx(ataCreationTx, 'Redeem.CreateATA');
595+
transaction.feePayer = senderAddress;
596+
yield this.createUnsignedTx({ transaction }, 'Redeem.CreateATA');
606597
}
607598
}
608599

@@ -611,19 +602,17 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
611602
vaa: TokenBridge.TransferVAA,
612603
unwrapNative: boolean = true,
613604
) {
614-
const { blockhash } = await SolanaPlatform.latestBlock(this.connection);
615-
616605
// Find the token address local to this chain
617606
const nativeAddress =
618607
vaa.payload.token.chain === this.chain
619608
? vaa.payload.token.address
620609
: (await this.getWrappedAsset(vaa.payload.token)).toUniversalAddress();
621610

622611
// Create an ATA if necessary
623-
yield* this.createAta(sender, nativeAddress, blockhash);
612+
yield* this.createAta(sender, nativeAddress);
624613

625614
// Post the VAA if necessary
626-
yield* this.coreBridge.postVaa(sender, vaa, blockhash);
615+
yield* this.coreBridge.postVaa(sender, vaa);
627616

628617
// redeem vaa and unwrap to native sol from wrapped sol
629618
if (unwrapNative) {
@@ -635,7 +624,7 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
635624
wrappedNative.toUint8Array(),
636625
)
637626
) {
638-
yield* this.redeemAndUnwrap(sender, vaa, blockhash);
627+
yield* this.redeemAndUnwrap(sender, vaa);
639628
return;
640629
}
641630
}
@@ -656,14 +645,12 @@ export class SolanaTokenBridge<N extends Network, C extends SolanaChains>
656645
vaa,
657646
),
658647
);
659-
660-
transaction.recentBlockhash = blockhash;
661648
transaction.feePayer = senderAddress;
662-
yield this.createUnsignedTx(transaction, 'Solana.RedeemTransfer');
649+
yield this.createUnsignedTx({ transaction }, 'Solana.RedeemTransfer');
663650
}
664651

665652
private createUnsignedTx(
666-
txReq: Transaction,
653+
txReq: SolanaTransaction,
667654
description: string,
668655
parallelizable: boolean = false,
669656
): SolanaUnsignedTransaction<N, C> {

0 commit comments

Comments
 (0)