Skip to content

Commit 1bef406

Browse files
authored
Escrow refactor ATA (js) (#109)
* Escrow refactor ATA (js) * Single signer helpers return instructions not transactions * Update CreateEscrowAccountResult type
1 parent 01888b9 commit 1bef406

File tree

15 files changed

+308
-256
lines changed

15 files changed

+308
-256
lines changed

clients/js/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# @solana-program/token-wrap
22

3+
## 2.0.0
4+
5+
### Major Changes
6+
7+
- Single signer helpers return instructions, not transactions
8+
39
## 1.0.0
410

511
### Major Changes

clients/js/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@solana-program/token-wrap",
3-
"version": "1.0.0",
3+
"version": "2.0.0",
44
"description": "Javascript helpers for interacting with the Solana Token Wrap program",
55
"author": "Anza Maintainers <[email protected]>",
66
"license": "Apache-2.0",
@@ -48,6 +48,7 @@
4848
"@solana-program/system": "^0.7.0",
4949
"@solana-program/token": "^0.5.1",
5050
"@solana-program/token-2022": "^0.4.1",
51+
"@solana/accounts": "^2.1.1",
5152
"@solana/rpc-types": "^2.1.1"
5253
},
5354
"devDependencies": {

clients/js/src/create-mint.ts

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
import {
22
Address,
3-
appendTransactionMessageInstructions,
4-
CompilableTransactionMessage,
5-
createTransactionMessage,
63
fetchEncodedAccount,
74
GetAccountInfoApi,
85
GetMinimumBalanceForRentExemptionApi,
96
IInstruction,
107
KeyPairSigner,
11-
pipe,
128
Rpc,
13-
setTransactionMessageFeePayerSigner,
14-
setTransactionMessageLifetimeUsingBlockhash,
15-
TransactionMessageWithBlockhashLifetime,
169
} from '@solana/kit';
1710
import { getMintSize } from '@solana-program/token-2022';
1811
import { getTransferSolInstruction } from '@solana-program/system';
@@ -22,36 +15,30 @@ import {
2215
getBackpointerSize,
2316
getCreateMintInstruction,
2417
} from './generated';
25-
import { Blockhash } from '@solana/rpc-types';
2618

27-
export interface CreateMintTxArgs {
19+
export interface CreateMintArgs {
2820
rpc: Rpc<GetAccountInfoApi & GetMinimumBalanceForRentExemptionApi>;
29-
blockhash: {
30-
blockhash: Blockhash;
31-
lastValidBlockHeight: bigint;
32-
};
3321
unwrappedMint: Address;
3422
wrappedTokenProgram: Address;
3523
payer: KeyPairSigner;
3624
idempotent: boolean;
3725
}
3826

39-
export interface CreateMintTxResult {
27+
export interface CreateMintResult {
4028
wrappedMint: Address;
4129
backpointer: Address;
4230
fundedWrappedMintLamports: bigint;
4331
fundedBackpointerLamports: bigint;
44-
tx: CompilableTransactionMessage & TransactionMessageWithBlockhashLifetime;
32+
ixs: IInstruction[];
4533
}
4634

47-
export async function createMintTx({
35+
export async function createMint({
4836
rpc,
49-
blockhash,
5037
unwrappedMint,
5138
wrappedTokenProgram,
5239
payer,
5340
idempotent = false,
54-
}: CreateMintTxArgs): Promise<CreateMintTxResult> {
41+
}: CreateMintArgs): Promise<CreateMintResult> {
5542
const [wrappedMint] = await findWrappedMintPda({
5643
unwrappedMint,
5744
wrappedTokenProgram: wrappedTokenProgram,
@@ -113,17 +100,10 @@ export async function createMintTx({
113100
}),
114101
);
115102

116-
const tx = pipe(
117-
createTransactionMessage({ version: 0 }),
118-
tx => setTransactionMessageFeePayerSigner(payer, tx),
119-
tx => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
120-
tx => appendTransactionMessageInstructions(instructions, tx),
121-
);
122-
123103
return {
124104
wrappedMint,
125105
backpointer,
126-
tx,
106+
ixs: instructions,
127107
fundedWrappedMintLamports,
128108
fundedBackpointerLamports,
129109
};

clients/js/src/examples/multisig.ts

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
import {
22
address,
3+
appendTransactionMessageInstructions,
34
createKeyPairSignerFromBytes,
45
createNoopSigner,
56
createSolanaRpc,
67
createSolanaRpcSubscriptions,
8+
createTransactionMessage,
79
getBase58Decoder,
810
getSignatureFromTransaction,
911
partiallySignTransactionMessageWithSigners,
12+
pipe,
1013
sendAndConfirmTransactionFactory,
14+
setTransactionMessageFeePayerSigner,
15+
setTransactionMessageLifetimeUsingBlockhash,
1116
signTransactionMessageWithSigners,
1217
} from '@solana/kit';
1318
import { TOKEN_2022_PROGRAM_ADDRESS } from '@solana-program/token-2022';
1419
import {
1520
findWrappedMintAuthorityPda,
1621
findWrappedMintPda,
17-
multisigOfflineSignWrapTx,
1822
combinedMultisigTx,
19-
createEscrowAccountTx,
20-
createMintTx,
23+
createMint,
2124
multisigOfflineSignUnwrap,
25+
createEscrowAccount,
26+
multisigOfflineSignWrap,
2227
} from '../index';
23-
import { createTokenAccountTx, getOwnerFromAccount } from '../utilities';
28+
import { createTokenAccount, getOwnerFromAccount } from '../utilities';
2429

2530
// Replace these consts with your own
2631
const PAYER_KEYPAIR_BYTES = new Uint8Array([
@@ -59,55 +64,77 @@ async function main() {
5964
const { value: blockhash } = await rpc.getLatestBlockhash().send();
6065

6166
// Initialize the wrapped mint
62-
const createMintMessage = await createMintTx({
67+
const createMintHelper = await createMint({
6368
rpc,
64-
blockhash,
6569
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
6670
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
6771
payer,
6872
idempotent: true,
6973
});
70-
const signedCreateMintTx = await signTransactionMessageWithSigners(createMintMessage.tx);
71-
await sendAndConfirm(signedCreateMintTx, { commitment: 'confirmed' });
72-
const createMintSignature = getSignatureFromTransaction(signedCreateMintTx);
74+
const createMintTx = await pipe(
75+
createTransactionMessage({ version: 0 }),
76+
tx => setTransactionMessageFeePayerSigner(payer, tx),
77+
tx => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
78+
tx => appendTransactionMessageInstructions(createMintHelper.ixs, tx),
79+
tx => signTransactionMessageWithSigners(tx),
80+
);
81+
await sendAndConfirm(createMintTx, { commitment: 'confirmed' });
82+
const createMintSignature = getSignatureFromTransaction(createMintTx);
7383

7484
console.log('======== Create Mint Successful ========');
75-
console.log('Wrapped Mint:', createMintMessage.wrappedMint);
76-
console.log('Backpointer:', createMintMessage.backpointer);
77-
console.log('Funded wrapped mint lamports:', createMintMessage.fundedWrappedMintLamports);
78-
console.log('Funded backpointer lamports:', createMintMessage.fundedBackpointerLamports);
85+
console.log('Wrapped Mint:', createMintHelper.wrappedMint);
86+
console.log('Backpointer:', createMintHelper.backpointer);
87+
console.log('Funded wrapped mint lamports:', createMintHelper.fundedWrappedMintLamports);
88+
console.log('Funded backpointer lamports:', createMintHelper.fundedBackpointerLamports);
7989
console.log('Signature:', createMintSignature);
8090

8191
// === Setup accounts needed for wrap ===
8292

8393
// Create escrow account that with hold unwrapped tokens
84-
const createEscrowMessage = await createEscrowAccountTx({
94+
const createEscrowHelper = await createEscrowAccount({
8595
rpc,
86-
blockhash,
8796
payer,
8897
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
8998
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
9099
});
91-
const signedCreateEscrowTx = await signTransactionMessageWithSigners(createEscrowMessage.tx);
92-
await sendAndConfirm(signedCreateEscrowTx, { commitment: 'confirmed' });
100+
if (createEscrowHelper.kind === 'instructions_to_create') {
101+
const createEscrowTx = await pipe(
102+
createTransactionMessage({ version: 0 }),
103+
tx => setTransactionMessageFeePayerSigner(payer, tx),
104+
tx => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
105+
tx => appendTransactionMessageInstructions(createEscrowHelper.ixs, tx),
106+
tx => signTransactionMessageWithSigners(tx),
107+
);
108+
await sendAndConfirm(createEscrowTx, { commitment: 'confirmed' });
109+
const createEscrowSignature = getSignatureFromTransaction(createEscrowTx);
110+
111+
console.log('======== Create Escrow Successful ========');
112+
console.log('Escrow address:', createEscrowHelper.address);
113+
console.log('Signature:', createEscrowSignature);
114+
} else {
115+
console.log('======== Escrow already exists, skipping creation ========');
116+
}
93117

94118
// Create recipient account where wrapped tokens will be minted to
95119
const [wrappedMint] = await findWrappedMintPda({
96120
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
97121
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
98122
});
99-
const recipientTokenAccountMessage = await createTokenAccountTx({
123+
const recipientTokenAccountHelper = await createTokenAccount({
100124
rpc,
101-
blockhash,
102125
payer,
103126
mint: wrappedMint,
104127
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
105128
owner: MULTISIG_SPL_TOKEN_2022,
106129
});
107-
const signedRecipientAccountTx = await signTransactionMessageWithSigners(
108-
recipientTokenAccountMessage.tx,
130+
const recipientTokenAccountTx = await pipe(
131+
createTransactionMessage({ version: 0 }),
132+
tx => setTransactionMessageFeePayerSigner(payer, tx),
133+
tx => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
134+
tx => appendTransactionMessageInstructions(recipientTokenAccountHelper.ixs, tx),
135+
tx => signTransactionMessageWithSigners(tx),
109136
);
110-
await sendAndConfirm(signedRecipientAccountTx, { commitment: 'confirmed' });
137+
await sendAndConfirm(recipientTokenAccountTx, { commitment: 'confirmed' });
111138

112139
const unwrappedTokenProgram = await getOwnerFromAccount(rpc, UNWRAPPED_TOKEN_ACCOUNT);
113140
const [wrappedMintAuthority] = await findWrappedMintAuthorityPda({ wrappedMint });
@@ -119,14 +146,13 @@ async function main() {
119146

120147
// Two signers and the payer sign the transaction independently
121148

122-
const wrapTxA = multisigOfflineSignWrapTx({
149+
const wrapTxA = await multisigOfflineSignWrap({
123150
payer: createNoopSigner(payer.address),
124151
unwrappedTokenAccount: UNWRAPPED_TOKEN_ACCOUNT,
125-
escrowAccount: createEscrowMessage.keyPair.address,
126152
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
127153
amount: AMOUNT_TO_WRAP,
128154
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
129-
recipientWrappedTokenAccount: recipientTokenAccountMessage.keyPair.address,
155+
recipientWrappedTokenAccount: recipientTokenAccountHelper.keyPair.address,
130156
transferAuthority: MULTISIG_SPL_TOKEN,
131157
wrappedMint,
132158
wrappedMintAuthority,
@@ -136,14 +162,13 @@ async function main() {
136162
});
137163
const signedWrapTxA = await partiallySignTransactionMessageWithSigners(wrapTxA);
138164

139-
const wrapTxB = multisigOfflineSignWrapTx({
165+
const wrapTxB = await multisigOfflineSignWrap({
140166
payer: createNoopSigner(payer.address),
141167
unwrappedTokenAccount: UNWRAPPED_TOKEN_ACCOUNT,
142-
escrowAccount: createEscrowMessage.keyPair.address,
143168
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
144169
amount: AMOUNT_TO_WRAP,
145170
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
146-
recipientWrappedTokenAccount: recipientTokenAccountMessage.keyPair.address,
171+
recipientWrappedTokenAccount: recipientTokenAccountHelper.keyPair.address,
147172
transferAuthority: MULTISIG_SPL_TOKEN,
148173
wrappedMint,
149174
wrappedMintAuthority,
@@ -153,14 +178,13 @@ async function main() {
153178
});
154179
const signedWrapTxB = await partiallySignTransactionMessageWithSigners(wrapTxB);
155180

156-
const wrapTxC = multisigOfflineSignWrapTx({
181+
const wrapTxC = await multisigOfflineSignWrap({
157182
payer,
158183
unwrappedTokenAccount: UNWRAPPED_TOKEN_ACCOUNT,
159-
escrowAccount: createEscrowMessage.keyPair.address,
160184
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
161185
amount: AMOUNT_TO_WRAP,
162186
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
163-
recipientWrappedTokenAccount: recipientTokenAccountMessage.keyPair.address,
187+
recipientWrappedTokenAccount: recipientTokenAccountHelper.keyPair.address,
164188
transferAuthority: MULTISIG_SPL_TOKEN,
165189
wrappedMint,
166190
wrappedMintAuthority,
@@ -192,13 +216,12 @@ async function main() {
192216

193217
const { value: unwrapBlockhash } = await rpc.getLatestBlockhash().send();
194218

195-
const unwrapTxA = multisigOfflineSignUnwrap({
219+
const unwrapTxA = await multisigOfflineSignUnwrap({
196220
payer: createNoopSigner(payer.address),
197-
unwrappedEscrow: createEscrowMessage.keyPair.address,
198221
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
199222
amount: AMOUNT_TO_WRAP,
200223
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
201-
wrappedTokenAccount: recipientTokenAccountMessage.keyPair.address,
224+
wrappedTokenAccount: recipientTokenAccountHelper.keyPair.address,
202225
recipientUnwrappedToken: UNWRAPPED_TOKEN_ACCOUNT,
203226
transferAuthority: MULTISIG_SPL_TOKEN_2022,
204227
wrappedMint,
@@ -209,13 +232,12 @@ async function main() {
209232
});
210233
const signedUnwrapTxA = await partiallySignTransactionMessageWithSigners(unwrapTxA);
211234

212-
const unwrapTxB = multisigOfflineSignUnwrap({
235+
const unwrapTxB = await multisigOfflineSignUnwrap({
213236
payer: createNoopSigner(payer.address),
214-
unwrappedEscrow: createEscrowMessage.keyPair.address,
215237
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
216238
amount: AMOUNT_TO_WRAP,
217239
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
218-
wrappedTokenAccount: recipientTokenAccountMessage.keyPair.address,
240+
wrappedTokenAccount: recipientTokenAccountHelper.keyPair.address,
219241
recipientUnwrappedToken: UNWRAPPED_TOKEN_ACCOUNT,
220242
transferAuthority: MULTISIG_SPL_TOKEN_2022,
221243
wrappedMint,
@@ -226,13 +248,12 @@ async function main() {
226248
});
227249
const signedUnwrapTxB = await partiallySignTransactionMessageWithSigners(unwrapTxB);
228250

229-
const unwrapTxC = multisigOfflineSignUnwrap({
251+
const unwrapTxC = await multisigOfflineSignUnwrap({
230252
payer: payer,
231-
unwrappedEscrow: createEscrowMessage.keyPair.address,
232253
wrappedTokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
233254
amount: AMOUNT_TO_WRAP,
234255
unwrappedMint: UNWRAPPED_MINT_ADDRESS,
235-
wrappedTokenAccount: recipientTokenAccountMessage.keyPair.address,
256+
wrappedTokenAccount: recipientTokenAccountHelper.keyPair.address,
236257
recipientUnwrappedToken: UNWRAPPED_TOKEN_ACCOUNT,
237258
transferAuthority: MULTISIG_SPL_TOKEN_2022,
238259
wrappedMint,

0 commit comments

Comments
 (0)