@solana-program/token-wrap 0.0.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,934 @@
1
+ import { getProgramDerivedAddress, getUtf8Encoder, getAddressEncoder, getStructEncoder, getStructDecoder, getAddressDecoder, combineCodec, decodeAccount, assertAccountExists, fetchEncodedAccount, assertAccountsExist, fetchEncodedAccounts, containsBytes, getU8Encoder, isProgramError, transformEncoder, getBooleanEncoder, getU8Decoder, getBooleanDecoder, getU64Encoder, getU64Decoder, AccountRole, pipe, createTransactionMessage, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, assertTransactionIsFullySigned, upgradeRoleToSigner, generateKeyPairSigner, isTransactionSigner as isTransactionSigner$1 } from '@solana/kit';
2
+ import { getMintSize, findAssociatedTokenPda, getTokenDecoder, TOKEN_2022_PROGRAM_ADDRESS, getInitializeAccountInstruction as getInitializeAccountInstruction$1 } from '@solana-program/token-2022';
3
+ import { getTransferSolInstruction, getCreateAccountInstruction } from '@solana-program/system';
4
+ import { TOKEN_PROGRAM_ADDRESS, getInitializeAccountInstruction } from '@solana-program/token';
5
+
6
+ // src/generated/accounts/backpointer.ts
7
+ async function findBackpointerPda(seeds, config = {}) {
8
+ const {
9
+ programAddress = "TwRapQCDhWkZRrDaHfZGuHxkZ91gHDRkyuzNqeU5MgR"
10
+ } = config;
11
+ return await getProgramDerivedAddress({
12
+ programAddress,
13
+ seeds: [
14
+ getUtf8Encoder().encode("backpointer"),
15
+ getAddressEncoder().encode(seeds.wrappedMint)
16
+ ]
17
+ });
18
+ }
19
+ async function findWrappedMintPda(seeds, config = {}) {
20
+ const {
21
+ programAddress = "TwRapQCDhWkZRrDaHfZGuHxkZ91gHDRkyuzNqeU5MgR"
22
+ } = config;
23
+ return await getProgramDerivedAddress({
24
+ programAddress,
25
+ seeds: [
26
+ getUtf8Encoder().encode("mint"),
27
+ getAddressEncoder().encode(seeds.unwrappedMint),
28
+ getAddressEncoder().encode(seeds.wrappedTokenProgram)
29
+ ]
30
+ });
31
+ }
32
+ async function findWrappedMintAuthorityPda(seeds, config = {}) {
33
+ const {
34
+ programAddress = "TwRapQCDhWkZRrDaHfZGuHxkZ91gHDRkyuzNqeU5MgR"
35
+ } = config;
36
+ return await getProgramDerivedAddress({
37
+ programAddress,
38
+ seeds: [
39
+ getUtf8Encoder().encode("authority"),
40
+ getAddressEncoder().encode(seeds.wrappedMint)
41
+ ]
42
+ });
43
+ }
44
+
45
+ // src/generated/accounts/backpointer.ts
46
+ function getBackpointerEncoder() {
47
+ return getStructEncoder([["unwrappedMint", getAddressEncoder()]]);
48
+ }
49
+ function getBackpointerDecoder() {
50
+ return getStructDecoder([["unwrappedMint", getAddressDecoder()]]);
51
+ }
52
+ function getBackpointerCodec() {
53
+ return combineCodec(getBackpointerEncoder(), getBackpointerDecoder());
54
+ }
55
+ function decodeBackpointer(encodedAccount) {
56
+ return decodeAccount(
57
+ encodedAccount,
58
+ getBackpointerDecoder()
59
+ );
60
+ }
61
+ async function fetchBackpointer(rpc, address, config) {
62
+ const maybeAccount = await fetchMaybeBackpointer(rpc, address, config);
63
+ assertAccountExists(maybeAccount);
64
+ return maybeAccount;
65
+ }
66
+ async function fetchMaybeBackpointer(rpc, address, config) {
67
+ const maybeAccount = await fetchEncodedAccount(rpc, address, config);
68
+ return decodeBackpointer(maybeAccount);
69
+ }
70
+ async function fetchAllBackpointer(rpc, addresses, config) {
71
+ const maybeAccounts = await fetchAllMaybeBackpointer(rpc, addresses, config);
72
+ assertAccountsExist(maybeAccounts);
73
+ return maybeAccounts;
74
+ }
75
+ async function fetchAllMaybeBackpointer(rpc, addresses, config) {
76
+ const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
77
+ return maybeAccounts.map((maybeAccount) => decodeBackpointer(maybeAccount));
78
+ }
79
+ function getBackpointerSize() {
80
+ return 32;
81
+ }
82
+ async function fetchBackpointerFromSeeds(rpc, seeds, config = {}) {
83
+ const maybeAccount = await fetchMaybeBackpointerFromSeeds(rpc, seeds, config);
84
+ assertAccountExists(maybeAccount);
85
+ return maybeAccount;
86
+ }
87
+ async function fetchMaybeBackpointerFromSeeds(rpc, seeds, config = {}) {
88
+ const { programAddress, ...fetchConfig } = config;
89
+ const [address] = await findBackpointerPda(seeds, { programAddress });
90
+ return await fetchMaybeBackpointer(rpc, address, fetchConfig);
91
+ }
92
+ var TOKEN_WRAP_PROGRAM_ADDRESS = "TwRapQCDhWkZRrDaHfZGuHxkZ91gHDRkyuzNqeU5MgR";
93
+ var TokenWrapAccount = /* @__PURE__ */ ((TokenWrapAccount2) => {
94
+ TokenWrapAccount2[TokenWrapAccount2["Backpointer"] = 0] = "Backpointer";
95
+ return TokenWrapAccount2;
96
+ })(TokenWrapAccount || {});
97
+ var TokenWrapInstruction = /* @__PURE__ */ ((TokenWrapInstruction2) => {
98
+ TokenWrapInstruction2[TokenWrapInstruction2["CreateMint"] = 0] = "CreateMint";
99
+ TokenWrapInstruction2[TokenWrapInstruction2["Wrap"] = 1] = "Wrap";
100
+ TokenWrapInstruction2[TokenWrapInstruction2["Unwrap"] = 2] = "Unwrap";
101
+ return TokenWrapInstruction2;
102
+ })(TokenWrapInstruction || {});
103
+ function identifyTokenWrapInstruction(instruction) {
104
+ const data = "data" in instruction ? instruction.data : instruction;
105
+ if (containsBytes(data, getU8Encoder().encode(0), 0)) {
106
+ return 0 /* CreateMint */;
107
+ }
108
+ if (containsBytes(data, getU8Encoder().encode(1), 0)) {
109
+ return 1 /* Wrap */;
110
+ }
111
+ if (containsBytes(data, getU8Encoder().encode(2), 0)) {
112
+ return 2 /* Unwrap */;
113
+ }
114
+ throw new Error(
115
+ "The provided instruction could not be identified as a tokenWrap instruction."
116
+ );
117
+ }
118
+
119
+ // src/generated/errors/tokenWrap.ts
120
+ var TOKEN_WRAP_ERROR__WRAPPED_MINT_MISMATCH = 0;
121
+ var TOKEN_WRAP_ERROR__BACKPOINTER_MISMATCH = 1;
122
+ var TOKEN_WRAP_ERROR__ZERO_WRAP_AMOUNT = 2;
123
+ var TOKEN_WRAP_ERROR__MINT_AUTHORITY_MISMATCH = 3;
124
+ var TOKEN_WRAP_ERROR__ESCROW_OWNER_MISMATCH = 4;
125
+ var TOKEN_WRAP_ERROR__INVALID_WRAPPED_MINT_OWNER = 5;
126
+ var TOKEN_WRAP_ERROR__INVALID_BACKPOINTER_OWNER = 6;
127
+ var tokenWrapErrorMessages;
128
+ if (process.env.NODE_ENV !== "production") {
129
+ tokenWrapErrorMessages = {
130
+ [TOKEN_WRAP_ERROR__BACKPOINTER_MISMATCH]: `Wrapped backpointer account address does not match expected PDA`,
131
+ [TOKEN_WRAP_ERROR__ESCROW_OWNER_MISMATCH]: `Unwrapped escrow token owner is not set to expected PDA`,
132
+ [TOKEN_WRAP_ERROR__INVALID_BACKPOINTER_OWNER]: `Wrapped backpointer account owner is not the expected token wrap program`,
133
+ [TOKEN_WRAP_ERROR__INVALID_WRAPPED_MINT_OWNER]: `Wrapped mint account owner is not the expected token program`,
134
+ [TOKEN_WRAP_ERROR__MINT_AUTHORITY_MISMATCH]: `Wrapped mint authority does not match expected PDA`,
135
+ [TOKEN_WRAP_ERROR__WRAPPED_MINT_MISMATCH]: `Wrapped mint account address does not match expected PDA`,
136
+ [TOKEN_WRAP_ERROR__ZERO_WRAP_AMOUNT]: `Wrap amount should be positive`
137
+ };
138
+ }
139
+ function getTokenWrapErrorMessage(code) {
140
+ if (process.env.NODE_ENV !== "production") {
141
+ return tokenWrapErrorMessages[code];
142
+ }
143
+ return "Error message not available in production bundles.";
144
+ }
145
+ function isTokenWrapError(error, transactionMessage, code) {
146
+ return isProgramError(
147
+ error,
148
+ transactionMessage,
149
+ TOKEN_WRAP_PROGRAM_ADDRESS,
150
+ code
151
+ );
152
+ }
153
+ function expectAddress(value) {
154
+ if (!value) {
155
+ throw new Error("Expected a Address.");
156
+ }
157
+ if (typeof value === "object" && "address" in value) {
158
+ return value.address;
159
+ }
160
+ if (Array.isArray(value)) {
161
+ return value[0];
162
+ }
163
+ return value;
164
+ }
165
+ function getAccountMetaFactory(programAddress, optionalAccountStrategy) {
166
+ return (account) => {
167
+ if (!account.value) {
168
+ return Object.freeze({
169
+ address: programAddress,
170
+ role: AccountRole.READONLY
171
+ });
172
+ }
173
+ const writableRole = account.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;
174
+ return Object.freeze({
175
+ address: expectAddress(account.value),
176
+ role: isTransactionSigner(account.value) ? upgradeRoleToSigner(writableRole) : writableRole,
177
+ ...isTransactionSigner(account.value) ? { signer: account.value } : {}
178
+ });
179
+ };
180
+ }
181
+ function isTransactionSigner(value) {
182
+ return !!value && typeof value === "object" && "address" in value && isTransactionSigner$1(value);
183
+ }
184
+
185
+ // src/generated/instructions/createMint.ts
186
+ var CREATE_MINT_DISCRIMINATOR = 0;
187
+ function getCreateMintDiscriminatorBytes() {
188
+ return getU8Encoder().encode(CREATE_MINT_DISCRIMINATOR);
189
+ }
190
+ function getCreateMintInstructionDataEncoder() {
191
+ return transformEncoder(
192
+ getStructEncoder([
193
+ ["discriminator", getU8Encoder()],
194
+ ["idempotent", getBooleanEncoder()]
195
+ ]),
196
+ (value) => ({
197
+ ...value,
198
+ discriminator: CREATE_MINT_DISCRIMINATOR,
199
+ idempotent: value.idempotent ?? false
200
+ })
201
+ );
202
+ }
203
+ function getCreateMintInstructionDataDecoder() {
204
+ return getStructDecoder([
205
+ ["discriminator", getU8Decoder()],
206
+ ["idempotent", getBooleanDecoder()]
207
+ ]);
208
+ }
209
+ function getCreateMintInstructionDataCodec() {
210
+ return combineCodec(
211
+ getCreateMintInstructionDataEncoder(),
212
+ getCreateMintInstructionDataDecoder()
213
+ );
214
+ }
215
+ function getCreateMintInstruction(input, config) {
216
+ const programAddress = config?.programAddress ?? TOKEN_WRAP_PROGRAM_ADDRESS;
217
+ const originalAccounts = {
218
+ wrappedMint: { value: input.wrappedMint ?? null, isWritable: true },
219
+ backpointer: { value: input.backpointer ?? null, isWritable: true },
220
+ unwrappedMint: { value: input.unwrappedMint ?? null, isWritable: false },
221
+ systemProgram: { value: input.systemProgram ?? null, isWritable: false },
222
+ wrappedTokenProgram: {
223
+ value: input.wrappedTokenProgram ?? null,
224
+ isWritable: false
225
+ }
226
+ };
227
+ const accounts = originalAccounts;
228
+ const args = { ...input };
229
+ if (!accounts.systemProgram.value) {
230
+ accounts.systemProgram.value = "11111111111111111111111111111111";
231
+ }
232
+ const getAccountMeta = getAccountMetaFactory(programAddress);
233
+ const instruction = {
234
+ accounts: [
235
+ getAccountMeta(accounts.wrappedMint),
236
+ getAccountMeta(accounts.backpointer),
237
+ getAccountMeta(accounts.unwrappedMint),
238
+ getAccountMeta(accounts.systemProgram),
239
+ getAccountMeta(accounts.wrappedTokenProgram)
240
+ ],
241
+ programAddress,
242
+ data: getCreateMintInstructionDataEncoder().encode(
243
+ args
244
+ )
245
+ };
246
+ return instruction;
247
+ }
248
+ function parseCreateMintInstruction(instruction) {
249
+ if (instruction.accounts.length < 5) {
250
+ throw new Error("Not enough accounts");
251
+ }
252
+ let accountIndex = 0;
253
+ const getNextAccount = () => {
254
+ const accountMeta = instruction.accounts[accountIndex];
255
+ accountIndex += 1;
256
+ return accountMeta;
257
+ };
258
+ const getNextOptionalAccount = () => {
259
+ const accountMeta = getNextAccount();
260
+ return accountMeta.address === TOKEN_WRAP_PROGRAM_ADDRESS ? void 0 : accountMeta;
261
+ };
262
+ return {
263
+ programAddress: instruction.programAddress,
264
+ accounts: {
265
+ wrappedMint: getNextAccount(),
266
+ backpointer: getNextAccount(),
267
+ unwrappedMint: getNextAccount(),
268
+ systemProgram: getNextOptionalAccount(),
269
+ wrappedTokenProgram: getNextAccount()
270
+ },
271
+ data: getCreateMintInstructionDataDecoder().decode(instruction.data)
272
+ };
273
+ }
274
+ var UNWRAP_DISCRIMINATOR = 2;
275
+ function getUnwrapDiscriminatorBytes() {
276
+ return getU8Encoder().encode(UNWRAP_DISCRIMINATOR);
277
+ }
278
+ function getUnwrapInstructionDataEncoder() {
279
+ return transformEncoder(
280
+ getStructEncoder([
281
+ ["discriminator", getU8Encoder()],
282
+ ["amount", getU64Encoder()]
283
+ ]),
284
+ (value) => ({ ...value, discriminator: UNWRAP_DISCRIMINATOR })
285
+ );
286
+ }
287
+ function getUnwrapInstructionDataDecoder() {
288
+ return getStructDecoder([
289
+ ["discriminator", getU8Decoder()],
290
+ ["amount", getU64Decoder()]
291
+ ]);
292
+ }
293
+ function getUnwrapInstructionDataCodec() {
294
+ return combineCodec(
295
+ getUnwrapInstructionDataEncoder(),
296
+ getUnwrapInstructionDataDecoder()
297
+ );
298
+ }
299
+ function getUnwrapInstruction(input, config) {
300
+ const programAddress = config?.programAddress ?? TOKEN_WRAP_PROGRAM_ADDRESS;
301
+ const originalAccounts = {
302
+ unwrappedEscrow: { value: input.unwrappedEscrow ?? null, isWritable: true },
303
+ recipientUnwrappedToken: {
304
+ value: input.recipientUnwrappedToken ?? null,
305
+ isWritable: true
306
+ },
307
+ wrappedMintAuthority: {
308
+ value: input.wrappedMintAuthority ?? null,
309
+ isWritable: false
310
+ },
311
+ unwrappedMint: { value: input.unwrappedMint ?? null, isWritable: false },
312
+ wrappedTokenProgram: {
313
+ value: input.wrappedTokenProgram ?? null,
314
+ isWritable: false
315
+ },
316
+ unwrappedTokenProgram: {
317
+ value: input.unwrappedTokenProgram ?? null,
318
+ isWritable: false
319
+ },
320
+ wrappedTokenAccount: {
321
+ value: input.wrappedTokenAccount ?? null,
322
+ isWritable: true
323
+ },
324
+ wrappedMint: { value: input.wrappedMint ?? null, isWritable: true },
325
+ transferAuthority: {
326
+ value: input.transferAuthority ?? null,
327
+ isWritable: false
328
+ }
329
+ };
330
+ const accounts = originalAccounts;
331
+ const args = { ...input };
332
+ const remainingAccounts = (args.multiSigners ?? []).map(
333
+ (signer) => ({
334
+ address: signer.address,
335
+ role: AccountRole.READONLY_SIGNER,
336
+ signer
337
+ })
338
+ );
339
+ const getAccountMeta = getAccountMetaFactory(programAddress);
340
+ const instruction = {
341
+ accounts: [
342
+ getAccountMeta(accounts.unwrappedEscrow),
343
+ getAccountMeta(accounts.recipientUnwrappedToken),
344
+ getAccountMeta(accounts.wrappedMintAuthority),
345
+ getAccountMeta(accounts.unwrappedMint),
346
+ getAccountMeta(accounts.wrappedTokenProgram),
347
+ getAccountMeta(accounts.unwrappedTokenProgram),
348
+ getAccountMeta(accounts.wrappedTokenAccount),
349
+ getAccountMeta(accounts.wrappedMint),
350
+ getAccountMeta(accounts.transferAuthority),
351
+ ...remainingAccounts
352
+ ],
353
+ programAddress,
354
+ data: getUnwrapInstructionDataEncoder().encode(
355
+ args
356
+ )
357
+ };
358
+ return instruction;
359
+ }
360
+ function parseUnwrapInstruction(instruction) {
361
+ if (instruction.accounts.length < 9) {
362
+ throw new Error("Not enough accounts");
363
+ }
364
+ let accountIndex = 0;
365
+ const getNextAccount = () => {
366
+ const accountMeta = instruction.accounts[accountIndex];
367
+ accountIndex += 1;
368
+ return accountMeta;
369
+ };
370
+ return {
371
+ programAddress: instruction.programAddress,
372
+ accounts: {
373
+ unwrappedEscrow: getNextAccount(),
374
+ recipientUnwrappedToken: getNextAccount(),
375
+ wrappedMintAuthority: getNextAccount(),
376
+ unwrappedMint: getNextAccount(),
377
+ wrappedTokenProgram: getNextAccount(),
378
+ unwrappedTokenProgram: getNextAccount(),
379
+ wrappedTokenAccount: getNextAccount(),
380
+ wrappedMint: getNextAccount(),
381
+ transferAuthority: getNextAccount()
382
+ },
383
+ data: getUnwrapInstructionDataDecoder().decode(instruction.data)
384
+ };
385
+ }
386
+ var WRAP_DISCRIMINATOR = 1;
387
+ function getWrapDiscriminatorBytes() {
388
+ return getU8Encoder().encode(WRAP_DISCRIMINATOR);
389
+ }
390
+ function getWrapInstructionDataEncoder() {
391
+ return transformEncoder(
392
+ getStructEncoder([
393
+ ["discriminator", getU8Encoder()],
394
+ ["amount", getU64Encoder()]
395
+ ]),
396
+ (value) => ({ ...value, discriminator: WRAP_DISCRIMINATOR })
397
+ );
398
+ }
399
+ function getWrapInstructionDataDecoder() {
400
+ return getStructDecoder([
401
+ ["discriminator", getU8Decoder()],
402
+ ["amount", getU64Decoder()]
403
+ ]);
404
+ }
405
+ function getWrapInstructionDataCodec() {
406
+ return combineCodec(
407
+ getWrapInstructionDataEncoder(),
408
+ getWrapInstructionDataDecoder()
409
+ );
410
+ }
411
+ function getWrapInstruction(input, config) {
412
+ const programAddress = config?.programAddress ?? TOKEN_WRAP_PROGRAM_ADDRESS;
413
+ const originalAccounts = {
414
+ recipientWrappedTokenAccount: {
415
+ value: input.recipientWrappedTokenAccount ?? null,
416
+ isWritable: true
417
+ },
418
+ wrappedMint: { value: input.wrappedMint ?? null, isWritable: true },
419
+ wrappedMintAuthority: {
420
+ value: input.wrappedMintAuthority ?? null,
421
+ isWritable: false
422
+ },
423
+ unwrappedTokenProgram: {
424
+ value: input.unwrappedTokenProgram ?? null,
425
+ isWritable: false
426
+ },
427
+ wrappedTokenProgram: {
428
+ value: input.wrappedTokenProgram ?? null,
429
+ isWritable: false
430
+ },
431
+ unwrappedTokenAccount: {
432
+ value: input.unwrappedTokenAccount ?? null,
433
+ isWritable: true
434
+ },
435
+ unwrappedMint: { value: input.unwrappedMint ?? null, isWritable: false },
436
+ unwrappedEscrow: { value: input.unwrappedEscrow ?? null, isWritable: true },
437
+ transferAuthority: {
438
+ value: input.transferAuthority ?? null,
439
+ isWritable: false
440
+ }
441
+ };
442
+ const accounts = originalAccounts;
443
+ const args = { ...input };
444
+ const remainingAccounts = (args.multiSigners ?? []).map(
445
+ (signer) => ({
446
+ address: signer.address,
447
+ role: AccountRole.READONLY_SIGNER,
448
+ signer
449
+ })
450
+ );
451
+ const getAccountMeta = getAccountMetaFactory(programAddress);
452
+ const instruction = {
453
+ accounts: [
454
+ getAccountMeta(accounts.recipientWrappedTokenAccount),
455
+ getAccountMeta(accounts.wrappedMint),
456
+ getAccountMeta(accounts.wrappedMintAuthority),
457
+ getAccountMeta(accounts.unwrappedTokenProgram),
458
+ getAccountMeta(accounts.wrappedTokenProgram),
459
+ getAccountMeta(accounts.unwrappedTokenAccount),
460
+ getAccountMeta(accounts.unwrappedMint),
461
+ getAccountMeta(accounts.unwrappedEscrow),
462
+ getAccountMeta(accounts.transferAuthority),
463
+ ...remainingAccounts
464
+ ],
465
+ programAddress,
466
+ data: getWrapInstructionDataEncoder().encode(
467
+ args
468
+ )
469
+ };
470
+ return instruction;
471
+ }
472
+ function parseWrapInstruction(instruction) {
473
+ if (instruction.accounts.length < 9) {
474
+ throw new Error("Not enough accounts");
475
+ }
476
+ let accountIndex = 0;
477
+ const getNextAccount = () => {
478
+ const accountMeta = instruction.accounts[accountIndex];
479
+ accountIndex += 1;
480
+ return accountMeta;
481
+ };
482
+ return {
483
+ programAddress: instruction.programAddress,
484
+ accounts: {
485
+ recipientWrappedTokenAccount: getNextAccount(),
486
+ wrappedMint: getNextAccount(),
487
+ wrappedMintAuthority: getNextAccount(),
488
+ unwrappedTokenProgram: getNextAccount(),
489
+ wrappedTokenProgram: getNextAccount(),
490
+ unwrappedTokenAccount: getNextAccount(),
491
+ unwrappedMint: getNextAccount(),
492
+ unwrappedEscrow: getNextAccount(),
493
+ transferAuthority: getNextAccount()
494
+ },
495
+ data: getWrapInstructionDataDecoder().decode(instruction.data)
496
+ };
497
+ }
498
+ async function createMintTx({
499
+ rpc,
500
+ blockhash,
501
+ unwrappedMint,
502
+ wrappedTokenProgram,
503
+ payer,
504
+ idempotent = false
505
+ }) {
506
+ const [wrappedMint] = await findWrappedMintPda({
507
+ unwrappedMint,
508
+ wrappedTokenProgram
509
+ });
510
+ const [backpointer] = await findBackpointerPda({ wrappedMint });
511
+ const instructions = [];
512
+ let fundedWrappedMintLamports = 0n;
513
+ const mintSize = BigInt(getMintSize());
514
+ const [wrappedMintAccount, wrappedMintRent] = await Promise.all([
515
+ fetchEncodedAccount(rpc, wrappedMint),
516
+ rpc.getMinimumBalanceForRentExemption(mintSize).send()
517
+ ]);
518
+ const wrappedMintLamports = wrappedMintAccount.exists ? wrappedMintAccount.lamports : 0n;
519
+ if (wrappedMintLamports < wrappedMintRent) {
520
+ fundedWrappedMintLamports = wrappedMintRent - wrappedMintLamports;
521
+ instructions.push(
522
+ getTransferSolInstruction({
523
+ source: payer,
524
+ destination: wrappedMint,
525
+ amount: fundedWrappedMintLamports
526
+ })
527
+ );
528
+ }
529
+ let fundedBackpointerLamports = 0n;
530
+ const backpointerSize = BigInt(getBackpointerSize());
531
+ const [backpointerAccount, backpointerRent] = await Promise.all([
532
+ fetchEncodedAccount(rpc, backpointer),
533
+ rpc.getMinimumBalanceForRentExemption(backpointerSize).send()
534
+ ]);
535
+ const backpointerLamports = backpointerAccount.exists ? backpointerAccount.lamports : 0n;
536
+ if (backpointerLamports < backpointerRent) {
537
+ fundedBackpointerLamports = backpointerRent - backpointerLamports;
538
+ instructions.push(
539
+ getTransferSolInstruction({
540
+ source: payer,
541
+ destination: backpointer,
542
+ amount: fundedBackpointerLamports
543
+ })
544
+ );
545
+ }
546
+ instructions.push(
547
+ getCreateMintInstruction({
548
+ wrappedMint,
549
+ backpointer,
550
+ unwrappedMint,
551
+ wrappedTokenProgram,
552
+ idempotent
553
+ })
554
+ );
555
+ const tx = pipe(
556
+ createTransactionMessage({ version: 0 }),
557
+ (tx2) => setTransactionMessageFeePayerSigner(payer, tx2),
558
+ (tx2) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx2),
559
+ (tx2) => appendTransactionMessageInstructions(instructions, tx2)
560
+ );
561
+ return {
562
+ wrappedMint,
563
+ backpointer,
564
+ tx,
565
+ fundedWrappedMintLamports,
566
+ fundedBackpointerLamports
567
+ };
568
+ }
569
+ function getInitializeTokenFn(tokenProgram) {
570
+ if (tokenProgram === TOKEN_PROGRAM_ADDRESS) return getInitializeAccountInstruction;
571
+ if (tokenProgram === TOKEN_2022_PROGRAM_ADDRESS) return getInitializeAccountInstruction$1;
572
+ throw new Error(`${tokenProgram} is not a valid token program.`);
573
+ }
574
+ async function createTokenAccountTx({
575
+ rpc,
576
+ blockhash,
577
+ payer,
578
+ mint,
579
+ owner,
580
+ tokenProgram
581
+ }) {
582
+ const [keyPair, lamports] = await Promise.all([
583
+ generateKeyPairSigner(),
584
+ rpc.getMinimumBalanceForRentExemption(165n).send()
585
+ ]);
586
+ const createAccountIx = getCreateAccountInstruction({
587
+ payer,
588
+ newAccount: keyPair,
589
+ lamports,
590
+ space: 165,
591
+ programAddress: tokenProgram
592
+ });
593
+ const initializeAccountIx = getInitializeTokenFn(tokenProgram)({
594
+ account: keyPair.address,
595
+ mint,
596
+ owner
597
+ });
598
+ const tx = pipe(
599
+ createTransactionMessage({ version: 0 }),
600
+ (tx2) => setTransactionMessageFeePayerSigner(payer, tx2),
601
+ (tx2) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx2),
602
+ (tx2) => appendTransactionMessageInstructions([createAccountIx, initializeAccountIx], tx2)
603
+ );
604
+ return {
605
+ tx,
606
+ keyPair
607
+ };
608
+ }
609
+ async function createEscrowAccountTx({
610
+ rpc,
611
+ blockhash,
612
+ payer,
613
+ unwrappedMint,
614
+ wrappedTokenProgram
615
+ }) {
616
+ const [wrappedMint] = await findWrappedMintPda({ unwrappedMint, wrappedTokenProgram });
617
+ const [wrappedMintAuthority] = await findWrappedMintAuthorityPda({ wrappedMint });
618
+ const unwrappedTokenProgram = await getOwnerFromAccount(rpc, unwrappedMint);
619
+ return createTokenAccountTx({
620
+ rpc,
621
+ blockhash,
622
+ payer,
623
+ mint: unwrappedMint,
624
+ owner: wrappedMintAuthority,
625
+ tokenProgram: unwrappedTokenProgram
626
+ });
627
+ }
628
+ async function getOwnerFromAccount(rpc, accountAddress) {
629
+ const accountInfo = await rpc.getAccountInfo(accountAddress, { encoding: "base64" }).send();
630
+ if (!accountInfo.value) {
631
+ throw new Error(`Account ${accountAddress} not found.`);
632
+ }
633
+ return accountInfo.value.owner;
634
+ }
635
+ async function getMintFromTokenAccount(rpc, tokenAccountAddress) {
636
+ const account = await fetchEncodedAccount(rpc, tokenAccountAddress);
637
+ if (!account.exists) {
638
+ throw new Error(`Unwrapped token account ${tokenAccountAddress} not found.`);
639
+ }
640
+ return getTokenDecoder().decode(account.data).mint;
641
+ }
642
+ function messageBytesEqual(results) {
643
+ if (results.length === 1) {
644
+ return true;
645
+ }
646
+ const reference = results[0];
647
+ if (!reference) throw new Error("No transactions in input");
648
+ return results.every(
649
+ (c) => reference.messageBytes.length === c.messageBytes.length && containsBytes(reference.messageBytes, c.messageBytes, 0)
650
+ );
651
+ }
652
+ function combineSignatures(signedTxs) {
653
+ const firstSignedTx = signedTxs[0];
654
+ if (!firstSignedTx) {
655
+ throw new Error("No signed transactions provided");
656
+ }
657
+ const allSignatures = {};
658
+ for (const pubkey of Object.keys(firstSignedTx.signatures)) {
659
+ allSignatures[pubkey] = null;
660
+ }
661
+ for (const signedTx of signedTxs) {
662
+ for (const [address, signature] of Object.entries(signedTx.signatures)) {
663
+ if (signature) {
664
+ allSignatures[address] = signature;
665
+ }
666
+ }
667
+ }
668
+ const missingSigners = [];
669
+ for (const [pubkey, signature] of Object.entries(allSignatures)) {
670
+ if (signature === null) {
671
+ missingSigners.push(pubkey);
672
+ }
673
+ }
674
+ if (missingSigners.length > 0) {
675
+ throw new Error(`Missing signatures for: ${missingSigners.join(", ")}`);
676
+ }
677
+ return allSignatures;
678
+ }
679
+ function combinedMultisigTx({
680
+ signedTxs,
681
+ blockhash
682
+ }) {
683
+ const messagesEqual = messageBytesEqual(signedTxs);
684
+ if (!messagesEqual) throw new Error("Messages are not all the same");
685
+ if (!signedTxs[0]) throw new Error("No signed transactions provided");
686
+ const tx = {
687
+ messageBytes: signedTxs[0].messageBytes,
688
+ signatures: combineSignatures(signedTxs),
689
+ lifetimeConstraint: blockhash
690
+ };
691
+ assertTransactionIsFullySigned(tx);
692
+ return tx;
693
+ }
694
+ function multisigOfflineSignWrapTx(args) {
695
+ return buildWrapTransaction(args);
696
+ }
697
+ async function singleSignerWrapTx({
698
+ rpc,
699
+ blockhash,
700
+ payer,
701
+ unwrappedTokenAccount,
702
+ escrowAccount,
703
+ wrappedTokenProgram,
704
+ amount,
705
+ transferAuthority: inputTransferAuthority,
706
+ unwrappedMint: inputUnwrappedMint,
707
+ recipientWrappedTokenAccount: inputRecipientTokenAccount,
708
+ unwrappedTokenProgram: inputUnwrappedTokenProgram
709
+ }) {
710
+ const {
711
+ unwrappedMint,
712
+ unwrappedTokenProgram,
713
+ wrappedMint,
714
+ wrappedMintAuthority,
715
+ recipientWrappedTokenAccount,
716
+ transferAuthority
717
+ } = await resolveAddrs({
718
+ rpc,
719
+ payer,
720
+ inputTransferAuthority,
721
+ inputUnwrappedMint,
722
+ unwrappedTokenAccount,
723
+ inputUnwrappedTokenProgram,
724
+ wrappedTokenProgram,
725
+ inputRecipientTokenAccount
726
+ });
727
+ const tx = buildWrapTransaction({
728
+ blockhash,
729
+ payer,
730
+ unwrappedTokenAccount,
731
+ escrowAccount,
732
+ wrappedTokenProgram,
733
+ amount,
734
+ transferAuthority,
735
+ unwrappedMint,
736
+ wrappedMint,
737
+ wrappedMintAuthority,
738
+ recipientWrappedTokenAccount,
739
+ unwrappedTokenProgram
740
+ });
741
+ return {
742
+ tx,
743
+ recipientWrappedTokenAccount,
744
+ escrowAccount,
745
+ amount: BigInt(amount)
746
+ };
747
+ }
748
+ async function resolveAddrs({
749
+ rpc,
750
+ payer,
751
+ unwrappedTokenAccount,
752
+ wrappedTokenProgram,
753
+ inputTransferAuthority,
754
+ inputUnwrappedMint,
755
+ inputRecipientTokenAccount,
756
+ inputUnwrappedTokenProgram
757
+ }) {
758
+ const unwrappedMint = inputUnwrappedMint ?? await getMintFromTokenAccount(rpc, unwrappedTokenAccount);
759
+ const unwrappedTokenProgram = inputUnwrappedTokenProgram ?? await getOwnerFromAccount(rpc, unwrappedTokenAccount);
760
+ const [wrappedMint] = await findWrappedMintPda({ unwrappedMint, wrappedTokenProgram });
761
+ const [wrappedMintAuthority] = await findWrappedMintAuthorityPda({ wrappedMint });
762
+ const recipientWrappedTokenAccount = inputRecipientTokenAccount ?? (await findAssociatedTokenPda({
763
+ owner: payer.address,
764
+ mint: wrappedMint,
765
+ tokenProgram: wrappedTokenProgram
766
+ }))[0];
767
+ const transferAuthority = inputTransferAuthority ?? payer;
768
+ return {
769
+ transferAuthority,
770
+ unwrappedMint,
771
+ unwrappedTokenProgram,
772
+ wrappedMint,
773
+ wrappedMintAuthority,
774
+ recipientWrappedTokenAccount
775
+ };
776
+ }
777
+ function buildWrapTransaction({
778
+ payer,
779
+ unwrappedTokenAccount,
780
+ escrowAccount,
781
+ wrappedTokenProgram,
782
+ amount,
783
+ transferAuthority,
784
+ unwrappedMint,
785
+ recipientWrappedTokenAccount,
786
+ unwrappedTokenProgram,
787
+ wrappedMint,
788
+ wrappedMintAuthority,
789
+ blockhash,
790
+ multiSigners = []
791
+ }) {
792
+ const wrapInstructionInput = {
793
+ recipientWrappedTokenAccount,
794
+ wrappedMint,
795
+ wrappedMintAuthority,
796
+ unwrappedTokenProgram,
797
+ wrappedTokenProgram,
798
+ unwrappedTokenAccount,
799
+ unwrappedMint,
800
+ unwrappedEscrow: escrowAccount,
801
+ transferAuthority,
802
+ amount: BigInt(amount),
803
+ multiSigners
804
+ };
805
+ const wrapInstruction = getWrapInstruction(wrapInstructionInput);
806
+ return pipe(
807
+ createTransactionMessage({ version: 0 }),
808
+ (tx) => setTransactionMessageFeePayerSigner(payer, tx),
809
+ (tx) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
810
+ (tx) => appendTransactionMessageInstructions([wrapInstruction], tx)
811
+ );
812
+ }
813
+ async function resolveUnwrapAddrs({
814
+ rpc,
815
+ payer,
816
+ wrappedTokenAccount,
817
+ unwrappedEscrow,
818
+ inputUnwrappedMint,
819
+ inputTransferAuthority,
820
+ inputWrappedTokenProgram,
821
+ inputUnwrappedTokenProgram
822
+ }) {
823
+ const wrappedTokenProgram = inputWrappedTokenProgram ?? await getOwnerFromAccount(rpc, wrappedTokenAccount);
824
+ const unwrappedTokenProgram = inputUnwrappedTokenProgram ?? await getOwnerFromAccount(rpc, unwrappedEscrow);
825
+ const unwrappedMint = inputUnwrappedMint ?? await getMintFromTokenAccount(rpc, unwrappedEscrow);
826
+ const wrappedAccountInfo = await fetchEncodedAccount(rpc, wrappedTokenAccount);
827
+ if (!wrappedAccountInfo.exists) {
828
+ throw new Error(`Wrapped token account ${wrappedTokenAccount} not found.`);
829
+ }
830
+ const wrappedMint = getTokenDecoder().decode(wrappedAccountInfo.data).mint;
831
+ const [wrappedMintAuthority] = await findWrappedMintAuthorityPda({ wrappedMint });
832
+ const transferAuthority = inputTransferAuthority ?? payer;
833
+ return {
834
+ unwrappedMint,
835
+ wrappedMint,
836
+ wrappedMintAuthority,
837
+ transferAuthority,
838
+ wrappedTokenProgram,
839
+ unwrappedTokenProgram
840
+ };
841
+ }
842
+ function buildUnwrapTransaction({
843
+ payer,
844
+ unwrappedEscrow,
845
+ recipientUnwrappedToken,
846
+ wrappedMintAuthority,
847
+ unwrappedMint,
848
+ wrappedTokenProgram,
849
+ unwrappedTokenProgram,
850
+ wrappedTokenAccount,
851
+ wrappedMint,
852
+ transferAuthority,
853
+ amount,
854
+ blockhash,
855
+ multiSigners = []
856
+ }) {
857
+ const unwrapInstructionInput = {
858
+ unwrappedEscrow,
859
+ recipientUnwrappedToken,
860
+ wrappedMintAuthority,
861
+ unwrappedMint,
862
+ wrappedTokenProgram,
863
+ unwrappedTokenProgram,
864
+ wrappedTokenAccount,
865
+ wrappedMint,
866
+ transferAuthority,
867
+ amount: BigInt(amount),
868
+ multiSigners
869
+ };
870
+ const unwrapInstruction = getUnwrapInstruction(unwrapInstructionInput);
871
+ return pipe(
872
+ createTransactionMessage({ version: 0 }),
873
+ (tx) => setTransactionMessageFeePayerSigner(payer, tx),
874
+ (tx) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
875
+ (tx) => appendTransactionMessageInstructions([unwrapInstruction], tx)
876
+ );
877
+ }
878
+ async function singleSignerUnwrapTx({
879
+ rpc,
880
+ blockhash,
881
+ payer,
882
+ wrappedTokenAccount,
883
+ unwrappedEscrow,
884
+ amount,
885
+ recipientUnwrappedToken,
886
+ transferAuthority: inputTransferAuthority,
887
+ unwrappedMint: inputUnwrappedMint,
888
+ wrappedTokenProgram: inputWrappedTokenProgram,
889
+ unwrappedTokenProgram: inputUnwrappedTokenProgram
890
+ }) {
891
+ const {
892
+ wrappedMint,
893
+ wrappedMintAuthority,
894
+ transferAuthority,
895
+ unwrappedTokenProgram,
896
+ unwrappedMint,
897
+ wrappedTokenProgram
898
+ } = await resolveUnwrapAddrs({
899
+ rpc,
900
+ payer,
901
+ wrappedTokenAccount,
902
+ unwrappedEscrow,
903
+ inputUnwrappedMint,
904
+ inputTransferAuthority,
905
+ inputWrappedTokenProgram,
906
+ inputUnwrappedTokenProgram
907
+ });
908
+ const tx = buildUnwrapTransaction({
909
+ payer,
910
+ unwrappedEscrow,
911
+ recipientUnwrappedToken,
912
+ wrappedMintAuthority,
913
+ unwrappedMint,
914
+ wrappedTokenProgram,
915
+ unwrappedTokenProgram,
916
+ wrappedTokenAccount,
917
+ wrappedMint,
918
+ transferAuthority,
919
+ amount,
920
+ blockhash
921
+ });
922
+ return {
923
+ recipientUnwrappedToken,
924
+ amount: BigInt(amount),
925
+ tx
926
+ };
927
+ }
928
+ function multisigOfflineSignUnwrap(args) {
929
+ return buildUnwrapTransaction(args);
930
+ }
931
+
932
+ export { CREATE_MINT_DISCRIMINATOR, TOKEN_WRAP_ERROR__BACKPOINTER_MISMATCH, TOKEN_WRAP_ERROR__ESCROW_OWNER_MISMATCH, TOKEN_WRAP_ERROR__INVALID_BACKPOINTER_OWNER, TOKEN_WRAP_ERROR__INVALID_WRAPPED_MINT_OWNER, TOKEN_WRAP_ERROR__MINT_AUTHORITY_MISMATCH, TOKEN_WRAP_ERROR__WRAPPED_MINT_MISMATCH, TOKEN_WRAP_ERROR__ZERO_WRAP_AMOUNT, TOKEN_WRAP_PROGRAM_ADDRESS, TokenWrapAccount, TokenWrapInstruction, UNWRAP_DISCRIMINATOR, WRAP_DISCRIMINATOR, combinedMultisigTx, createEscrowAccountTx, createMintTx, decodeBackpointer, fetchAllBackpointer, fetchAllMaybeBackpointer, fetchBackpointer, fetchBackpointerFromSeeds, fetchMaybeBackpointer, fetchMaybeBackpointerFromSeeds, findBackpointerPda, findWrappedMintAuthorityPda, findWrappedMintPda, getBackpointerCodec, getBackpointerDecoder, getBackpointerEncoder, getBackpointerSize, getCreateMintDiscriminatorBytes, getCreateMintInstruction, getCreateMintInstructionDataCodec, getCreateMintInstructionDataDecoder, getCreateMintInstructionDataEncoder, getTokenWrapErrorMessage, getUnwrapDiscriminatorBytes, getUnwrapInstruction, getUnwrapInstructionDataCodec, getUnwrapInstructionDataDecoder, getUnwrapInstructionDataEncoder, getWrapDiscriminatorBytes, getWrapInstruction, getWrapInstructionDataCodec, getWrapInstructionDataDecoder, getWrapInstructionDataEncoder, identifyTokenWrapInstruction, isTokenWrapError, multisigOfflineSignUnwrap, multisigOfflineSignWrapTx, parseCreateMintInstruction, parseUnwrapInstruction, parseWrapInstruction, singleSignerUnwrapTx, singleSignerWrapTx };
933
+ //# sourceMappingURL=index.mjs.map
934
+ //# sourceMappingURL=index.mjs.map