Skip to content

Commit 2bfeb4e

Browse files
committed
solana session authority changes
1 parent a0e6931 commit 2bfeb4e

File tree

2 files changed

+122
-87
lines changed

2 files changed

+122
-87
lines changed

wormhole-connect/src/routes/ntt/platforms/solana/nttManager.ts

+64-17
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
import { associatedAddress } from '@coral-xyz/anchor/dist/cjs/utils/token';
3737
import { NttQuoter } from './nttQuoter';
3838
import { getTokenById } from 'utils';
39+
import { Keccak } from 'sha3';
3940

4041
// TODO: make sure this is in sync with the contract
4142
const RATE_LIMIT_DURATION = 24 * 60 * 60;
@@ -47,6 +48,13 @@ type OutboxRateLimit =
4748
type InboxRateLimit =
4849
IdlAccounts<ExampleNativeTokenTransfers>['inboxRateLimit'];
4950

51+
interface TransferArgs {
52+
amount: BN;
53+
recipientChain: { id: ChainId };
54+
recipientAddress: number[];
55+
shouldQueue: boolean;
56+
}
57+
5058
export class NttManagerSolana {
5159
readonly connection: Connection;
5260
readonly program: Program<ExampleNativeTokenTransfers>;
@@ -100,9 +108,15 @@ export class NttManagerSolana {
100108
outboxItem: outboxItem.publicKey,
101109
revertOnDelay: !txArgs.shouldQueue,
102110
});
111+
const transferArgs: TransferArgs = {
112+
amount: txArgs.amount,
113+
recipientChain: { id: wh.toChainId(txArgs.recipientChain) },
114+
recipientAddress: Array.from(txArgs.recipientAddress),
115+
shouldQueue: txArgs.shouldQueue,
116+
};
103117
const approveIx = createApproveInstruction(
104118
tokenAccount,
105-
this.tokenAuthorityAddress(),
119+
this.sessionAuthorityAddress(txArgs.fromAuthority, transferArgs),
106120
payer,
107121
BigInt(amount.toString()),
108122
);
@@ -349,7 +363,7 @@ export class NttManagerSolana {
349363

350364
// Account addresses
351365

352-
derive_pda(seeds: Buffer | Array<Uint8Array | Buffer>): PublicKey {
366+
derivePda(seeds: Buffer | Array<Uint8Array | Buffer>): PublicKey {
353367
const seedsArray = seeds instanceof Buffer ? [seeds] : seeds;
354368
const [address] = PublicKey.findProgramAddressSync(
355369
seedsArray,
@@ -359,51 +373,68 @@ export class NttManagerSolana {
359373
}
360374

361375
configAccountAddress(): PublicKey {
362-
return this.derive_pda(Buffer.from('config'));
376+
return this.derivePda(Buffer.from('config'));
363377
}
364378

365379
outboxRateLimitAccountAddress(): PublicKey {
366-
return this.derive_pda(Buffer.from('outbox_rate_limit'));
380+
return this.derivePda(Buffer.from('outbox_rate_limit'));
367381
}
368382

369383
inboxRateLimitAccountAddress(chain: ChainName | ChainId): PublicKey {
370384
const chainId = wh.toChainId(chain);
371-
return this.derive_pda([
385+
return this.derivePda([
372386
Buffer.from('inbox_rate_limit'),
373387
new BN(chainId).toBuffer('be', 2),
374388
]);
375389
}
376390

377391
inboxItemAccountAddress(messageDigest: string): PublicKey {
378-
return this.derive_pda([
392+
return this.derivePda([
379393
Buffer.from('inbox_item'),
380394
Buffer.from(messageDigest.slice(2), 'hex'),
381395
]);
382396
}
383397

398+
sessionAuthorityAddress(sender: PublicKey, args: TransferArgs): PublicKey {
399+
const { amount, recipientChain, recipientAddress, shouldQueue } = args;
400+
const serialized = Buffer.concat([
401+
amount.toArrayLike(Buffer, 'be', 8),
402+
Buffer.from(new BN(recipientChain.id).toArrayLike(Buffer, 'be', 2)),
403+
Buffer.from(new Uint8Array(recipientAddress)),
404+
Buffer.from([shouldQueue ? 1 : 0]),
405+
]);
406+
const hasher = new Keccak(256);
407+
hasher.update(serialized);
408+
return this.derivePda([
409+
Buffer.from('session_authority'),
410+
sender.toBytes(),
411+
hasher.digest(),
412+
]);
413+
}
414+
384415
tokenAuthorityAddress(): PublicKey {
385-
return this.derive_pda([Buffer.from('token_authority')]);
416+
return this.derivePda([Buffer.from('token_authority')]);
386417
}
387418

388419
emitterAccountAddress(): PublicKey {
389-
return this.derive_pda([Buffer.from('emitter')]);
420+
return this.derivePda([Buffer.from('emitter')]);
390421
}
391422

392423
wormholeMessageAccountAddress(outboxItem: PublicKey): PublicKey {
393-
return this.derive_pda([Buffer.from('message'), outboxItem.toBuffer()]);
424+
return this.derivePda([Buffer.from('message'), outboxItem.toBuffer()]);
394425
}
395426

396427
peerAccountAddress(chain: ChainName | ChainId): PublicKey {
397428
const chainId = wh.toChainId(chain);
398-
return this.derive_pda([
429+
return this.derivePda([
399430
Buffer.from('peer'),
400431
new BN(chainId).toBuffer('be', 2),
401432
]);
402433
}
403434

404435
transceiverPeerAccountAddress(chain: ChainName | ChainId): PublicKey {
405436
const chainId = wh.toChainId(chain);
406-
return this.derive_pda([
437+
return this.derivePda([
407438
Buffer.from('transceiver_peer'),
408439
new BN(chainId).toBuffer('be', 2),
409440
]);
@@ -417,15 +448,15 @@ export class NttManagerSolana {
417448
if (id.length !== 32) {
418449
throw new Error('id must be 32 bytes');
419450
}
420-
return this.derive_pda([
451+
return this.derivePda([
421452
Buffer.from('transceiver_message'),
422453
new BN(chainId).toBuffer('be', 2),
423454
id,
424455
]);
425456
}
426457

427458
registeredTransceiverAddress(transceiver: PublicKey): PublicKey {
428-
return this.derive_pda([
459+
return this.derivePda([
429460
Buffer.from('registered_transceiver'),
430461
transceiver.toBuffer(),
431462
]);
@@ -451,6 +482,12 @@ export class NttManagerSolana {
451482
const config = await this.getConfig(args.config);
452483
const chainId = wh.toChainId(args.recipientChain);
453484
const mint = await this.mintAccountAddress(config);
485+
const transferArgs: TransferArgs = {
486+
amount: args.amount,
487+
recipientChain: { id: chainId },
488+
recipientAddress: Array.from(args.recipientAddress),
489+
shouldQueue: args.shouldQueue,
490+
};
454491
return await this.program.methods
455492
.transferBurn({
456493
amount: args.amount,
@@ -464,13 +501,15 @@ export class NttManagerSolana {
464501
config: { config: this.configAccountAddress() },
465502
mint,
466503
from: args.from,
467-
sender: args.fromAuthority,
468504
outboxItem: args.outboxItem,
469505
outboxRateLimit: this.outboxRateLimitAccountAddress(),
470-
tokenAuthority: this.tokenAuthorityAddress(),
471506
},
472507
peer: this.peerAccountAddress(args.recipientChain),
473508
inboxRateLimit: this.inboxRateLimitAccountAddress(args.recipientChain),
509+
sessionAuthority: this.sessionAuthorityAddress(
510+
args.fromAuthority,
511+
transferArgs,
512+
),
474513
})
475514
.instruction();
476515
}
@@ -493,6 +532,12 @@ export class NttManagerSolana {
493532
const config = await this.getConfig(args.config);
494533
const chainId = wh.toChainId(args.recipientChain);
495534
const mint = await this.mintAccountAddress(config);
535+
const transferArgs: TransferArgs = {
536+
amount: args.amount,
537+
recipientChain: { id: chainId },
538+
recipientAddress: Array.from(args.recipientAddress),
539+
shouldQueue: args.shouldQueue,
540+
};
496541
return await this.program.methods
497542
.transferLock({
498543
amount: args.amount,
@@ -506,15 +551,17 @@ export class NttManagerSolana {
506551
config: { config: this.configAccountAddress() },
507552
mint,
508553
from: args.from,
509-
sender: args.fromAuthority,
510554
tokenProgram: await this.tokenProgram(config),
511555
outboxItem: args.outboxItem,
512556
outboxRateLimit: this.outboxRateLimitAccountAddress(),
513-
tokenAuthority: this.tokenAuthorityAddress(),
514557
},
515558
peer: this.peerAccountAddress(args.recipientChain),
516559
inboxRateLimit: this.inboxRateLimitAccountAddress(args.recipientChain),
517560
custody: await this.custodyAccountAddress(config),
561+
sessionAuthority: this.sessionAuthorityAddress(
562+
args.fromAuthority,
563+
transferArgs,
564+
),
518565
})
519566
.instruction();
520567
}

0 commit comments

Comments
 (0)