@solana/transactions 2.0.0-experimental.0de6c3e → 2.0.0-experimental.0eb69ae
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.
- package/LICENSE +1 -1
- package/README.md +272 -5
- package/dist/index.browser.cjs +650 -281
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +637 -281
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +1317 -776
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +637 -281
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +652 -279
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +637 -281
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +22 -7
- package/dist/types/accounts.d.ts +3 -3
- package/dist/types/blockhash.d.ts +9 -1
- package/dist/types/compilable-transaction.d.ts +7 -0
- package/dist/types/compile-address-table-lookups.d.ts +2 -2
- package/dist/types/compile-instructions.d.ts +1 -1
- package/dist/types/compile-static-accounts.d.ts +2 -2
- package/dist/types/compile-transaction.d.ts +5 -6
- package/dist/types/decompile-transaction.d.ts +5 -0
- package/dist/types/durable-nonce.d.ts +23 -10
- package/dist/types/fee-payer.d.ts +4 -3
- package/dist/types/index.d.ts +3 -0
- package/dist/types/message.d.ts +1 -5
- package/dist/types/serializers/address-table-lookup.d.ts +5 -3
- package/dist/types/serializers/header.d.ts +4 -2
- package/dist/types/serializers/index.d.ts +3 -0
- package/dist/types/serializers/instruction.d.ts +4 -2
- package/dist/types/serializers/message.d.ts +4 -4
- package/dist/types/serializers/transaction-version.d.ts +4 -4
- package/dist/types/serializers/transaction.d.ts +6 -5
- package/dist/types/signatures.d.ts +10 -7
- package/dist/types/types.d.ts +13 -13
- package/dist/types/unsigned-transaction.d.ts +4 -0
- package/dist/types/wire-transaction.d.ts +2 -2
- package/package.json +24 -22
- package/dist/types/accounts.d.ts.map +0 -1
- package/dist/types/blockhash.d.ts.map +0 -1
- package/dist/types/compile-address-table-lookups.d.ts.map +0 -1
- package/dist/types/compile-header.d.ts.map +0 -1
- package/dist/types/compile-instructions.d.ts.map +0 -1
- package/dist/types/compile-lifetime-token.d.ts.map +0 -1
- package/dist/types/compile-static-accounts.d.ts.map +0 -1
- package/dist/types/compile-transaction.d.ts.map +0 -1
- package/dist/types/create-transaction.d.ts.map +0 -1
- package/dist/types/durable-nonce.d.ts.map +0 -1
- package/dist/types/fee-payer.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/instructions.d.ts.map +0 -1
- package/dist/types/message.d.ts.map +0 -1
- package/dist/types/serializers/address-table-lookup.d.ts.map +0 -1
- package/dist/types/serializers/header.d.ts.map +0 -1
- package/dist/types/serializers/instruction.d.ts.map +0 -1
- package/dist/types/serializers/message.d.ts.map +0 -1
- package/dist/types/serializers/transaction-version.d.ts.map +0 -1
- package/dist/types/serializers/transaction.d.ts.map +0 -1
- package/dist/types/serializers/unimplemented.d.ts +0 -3
- package/dist/types/serializers/unimplemented.d.ts.map +0 -1
- package/dist/types/signatures.d.ts.map +0 -1
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/wire-transaction.d.ts.map +0 -1
package/dist/index.browser.cjs
CHANGED
|
@@ -1,79 +1,74 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var codecsStrings = require('@solana/codecs-strings');
|
|
4
|
+
var addresses = require('@solana/addresses');
|
|
5
|
+
var codecsCore = require('@solana/codecs-core');
|
|
6
|
+
var codecsDataStructures = require('@solana/codecs-data-structures');
|
|
7
|
+
var codecsNumbers = require('@solana/codecs-numbers');
|
|
8
|
+
var functional = require('@solana/functional');
|
|
3
9
|
var keys = require('@solana/keys');
|
|
4
|
-
var umiSerializers = require('@metaplex-foundation/umi-serializers');
|
|
5
10
|
|
|
6
11
|
// ../build-scripts/env-shim.ts
|
|
7
12
|
var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
|
|
8
13
|
|
|
9
|
-
// src/
|
|
10
|
-
function
|
|
11
|
-
version
|
|
12
|
-
}) {
|
|
13
|
-
const out = {
|
|
14
|
-
instructions: [],
|
|
15
|
-
version
|
|
16
|
-
};
|
|
17
|
-
Object.freeze(out);
|
|
18
|
-
return out;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// src/fee-payer.ts
|
|
22
|
-
function setTransactionFeePayer(feePayer, transaction) {
|
|
23
|
-
if ("feePayer" in transaction && feePayer === transaction.feePayer) {
|
|
24
|
-
return transaction;
|
|
25
|
-
}
|
|
26
|
-
let out;
|
|
14
|
+
// src/unsigned-transaction.ts
|
|
15
|
+
function getUnsignedTransaction(transaction) {
|
|
27
16
|
if ("signatures" in transaction) {
|
|
28
17
|
const {
|
|
29
18
|
signatures: _,
|
|
30
19
|
// eslint-disable-line @typescript-eslint/no-unused-vars
|
|
31
20
|
...unsignedTransaction
|
|
32
21
|
} = transaction;
|
|
33
|
-
|
|
34
|
-
...unsignedTransaction,
|
|
35
|
-
feePayer
|
|
36
|
-
};
|
|
22
|
+
return unsignedTransaction;
|
|
37
23
|
} else {
|
|
38
|
-
|
|
39
|
-
...transaction,
|
|
40
|
-
feePayer
|
|
41
|
-
};
|
|
24
|
+
return transaction;
|
|
42
25
|
}
|
|
43
|
-
Object.freeze(out);
|
|
44
|
-
return out;
|
|
45
26
|
}
|
|
46
27
|
|
|
47
|
-
// src/
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
28
|
+
// src/blockhash.ts
|
|
29
|
+
var base58Encoder;
|
|
30
|
+
function assertIsBlockhash(putativeBlockhash) {
|
|
31
|
+
if (!base58Encoder)
|
|
32
|
+
base58Encoder = codecsStrings.getBase58Encoder();
|
|
33
|
+
try {
|
|
34
|
+
if (
|
|
35
|
+
// Lowest value (32 bytes of zeroes)
|
|
36
|
+
putativeBlockhash.length < 32 || // Highest value (32 bytes of 255)
|
|
37
|
+
putativeBlockhash.length > 44
|
|
38
|
+
) {
|
|
39
|
+
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
40
|
+
}
|
|
41
|
+
const bytes = base58Encoder.encode(putativeBlockhash);
|
|
42
|
+
const numBytes = bytes.byteLength;
|
|
43
|
+
if (numBytes !== 32) {
|
|
44
|
+
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
45
|
+
}
|
|
46
|
+
} catch (e) {
|
|
47
|
+
throw new Error(`\`${putativeBlockhash}\` is not a blockhash`, {
|
|
48
|
+
cause: e
|
|
49
|
+
});
|
|
65
50
|
}
|
|
66
|
-
return out;
|
|
67
51
|
}
|
|
68
|
-
function
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
|
|
53
|
+
if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
|
|
54
|
+
return transaction;
|
|
55
|
+
}
|
|
56
|
+
const out = {
|
|
57
|
+
...getUnsignedTransaction(transaction),
|
|
58
|
+
lifetimeConstraint: blockhashLifetimeConstraint
|
|
59
|
+
};
|
|
71
60
|
Object.freeze(out);
|
|
72
61
|
return out;
|
|
73
62
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
|
|
64
|
+
// src/create-transaction.ts
|
|
65
|
+
function createTransaction({
|
|
66
|
+
version
|
|
67
|
+
}) {
|
|
68
|
+
const out = {
|
|
69
|
+
instructions: [],
|
|
70
|
+
version
|
|
71
|
+
};
|
|
77
72
|
Object.freeze(out);
|
|
78
73
|
return out;
|
|
79
74
|
}
|
|
@@ -100,6 +95,113 @@ function isWritableRole(role) {
|
|
|
100
95
|
function mergeRoles(roleA, roleB) {
|
|
101
96
|
return roleA | roleB;
|
|
102
97
|
}
|
|
98
|
+
|
|
99
|
+
// src/durable-nonce.ts
|
|
100
|
+
var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
|
|
101
|
+
var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
102
|
+
function assertIsDurableNonceTransaction(transaction) {
|
|
103
|
+
if (!isDurableNonceTransaction(transaction)) {
|
|
104
|
+
throw new Error("Transaction is not a durable nonce transaction");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
|
|
108
|
+
return {
|
|
109
|
+
accounts: [
|
|
110
|
+
{ address: nonceAccountAddress, role: AccountRole.WRITABLE },
|
|
111
|
+
{
|
|
112
|
+
address: RECENT_BLOCKHASHES_SYSVAR_ADDRESS,
|
|
113
|
+
role: AccountRole.READONLY
|
|
114
|
+
},
|
|
115
|
+
{ address: nonceAuthorityAddress, role: AccountRole.READONLY_SIGNER }
|
|
116
|
+
],
|
|
117
|
+
data: new Uint8Array([4, 0, 0, 0]),
|
|
118
|
+
programAddress: SYSTEM_PROGRAM_ADDRESS
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function isAdvanceNonceAccountInstruction(instruction) {
|
|
122
|
+
return instruction.programAddress === SYSTEM_PROGRAM_ADDRESS && // Test for `AdvanceNonceAccount` instruction data
|
|
123
|
+
instruction.data != null && isAdvanceNonceAccountInstructionData(instruction.data) && // Test for exactly 3 accounts
|
|
124
|
+
instruction.accounts?.length === 3 && // First account is nonce account address
|
|
125
|
+
instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
|
|
126
|
+
instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
|
|
127
|
+
instruction.accounts[2].address != null && isSignerRole(instruction.accounts[2].role);
|
|
128
|
+
}
|
|
129
|
+
function isAdvanceNonceAccountInstructionData(data) {
|
|
130
|
+
return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
|
|
131
|
+
}
|
|
132
|
+
function isDurableNonceTransaction(transaction) {
|
|
133
|
+
return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
|
|
134
|
+
}
|
|
135
|
+
function isAdvanceNonceAccountInstructionForNonce(instruction, nonceAccountAddress, nonceAuthorityAddress) {
|
|
136
|
+
return instruction.accounts[0].address === nonceAccountAddress && instruction.accounts[2].address === nonceAuthorityAddress;
|
|
137
|
+
}
|
|
138
|
+
function setTransactionLifetimeUsingDurableNonce({
|
|
139
|
+
nonce,
|
|
140
|
+
nonceAccountAddress,
|
|
141
|
+
nonceAuthorityAddress
|
|
142
|
+
}, transaction) {
|
|
143
|
+
let newInstructions;
|
|
144
|
+
const firstInstruction = transaction.instructions[0];
|
|
145
|
+
if (firstInstruction && isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
146
|
+
if (isAdvanceNonceAccountInstructionForNonce(firstInstruction, nonceAccountAddress, nonceAuthorityAddress)) {
|
|
147
|
+
if (isDurableNonceTransaction(transaction) && transaction.lifetimeConstraint.nonce === nonce) {
|
|
148
|
+
return transaction;
|
|
149
|
+
} else {
|
|
150
|
+
newInstructions = [firstInstruction, ...transaction.instructions.slice(1)];
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
newInstructions = [
|
|
154
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
155
|
+
...transaction.instructions.slice(1)
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
newInstructions = [
|
|
160
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
161
|
+
...transaction.instructions
|
|
162
|
+
];
|
|
163
|
+
}
|
|
164
|
+
const out = {
|
|
165
|
+
...getUnsignedTransaction(transaction),
|
|
166
|
+
instructions: newInstructions,
|
|
167
|
+
lifetimeConstraint: {
|
|
168
|
+
nonce
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
Object.freeze(out);
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/fee-payer.ts
|
|
176
|
+
function setTransactionFeePayer(feePayer, transaction) {
|
|
177
|
+
if ("feePayer" in transaction && feePayer === transaction.feePayer) {
|
|
178
|
+
return transaction;
|
|
179
|
+
}
|
|
180
|
+
const out = {
|
|
181
|
+
...getUnsignedTransaction(transaction),
|
|
182
|
+
feePayer
|
|
183
|
+
};
|
|
184
|
+
Object.freeze(out);
|
|
185
|
+
return out;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// src/instructions.ts
|
|
189
|
+
function appendTransactionInstruction(instruction, transaction) {
|
|
190
|
+
const out = {
|
|
191
|
+
...getUnsignedTransaction(transaction),
|
|
192
|
+
instructions: [...transaction.instructions, instruction]
|
|
193
|
+
};
|
|
194
|
+
Object.freeze(out);
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
function prependTransactionInstruction(instruction, transaction) {
|
|
198
|
+
const out = {
|
|
199
|
+
...getUnsignedTransaction(transaction),
|
|
200
|
+
instructions: [instruction, ...transaction.instructions]
|
|
201
|
+
};
|
|
202
|
+
Object.freeze(out);
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
103
205
|
function upsert(addressMap, address, update) {
|
|
104
206
|
addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
|
|
105
207
|
}
|
|
@@ -152,7 +254,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
152
254
|
const shouldReplaceEntry = (
|
|
153
255
|
// Consider using the new LOOKUP_TABLE if its address is different...
|
|
154
256
|
entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
|
|
155
|
-
(addressComparator
|
|
257
|
+
(addressComparator ||= addresses.getAddressComparator())(
|
|
156
258
|
accountMeta.lookupTableAddress,
|
|
157
259
|
entry.lookupTableAddress
|
|
158
260
|
) < 0
|
|
@@ -258,7 +360,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
258
360
|
if (leftIsWritable !== isWritableRole(rightEntry.role)) {
|
|
259
361
|
return leftIsWritable ? -1 : 1;
|
|
260
362
|
}
|
|
261
|
-
addressComparator
|
|
363
|
+
addressComparator ||= addresses.getAddressComparator();
|
|
262
364
|
if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
|
|
263
365
|
return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
|
|
264
366
|
} else {
|
|
@@ -271,23 +373,22 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
271
373
|
return orderedAccounts;
|
|
272
374
|
}
|
|
273
375
|
function getCompiledAddressTableLookups(orderedAccounts) {
|
|
274
|
-
var _a;
|
|
275
376
|
const index = {};
|
|
276
377
|
for (const account of orderedAccounts) {
|
|
277
378
|
if (!("lookupTableAddress" in account)) {
|
|
278
379
|
continue;
|
|
279
380
|
}
|
|
280
|
-
const entry = index[
|
|
381
|
+
const entry = index[account.lookupTableAddress] ||= {
|
|
281
382
|
readableIndices: [],
|
|
282
383
|
writableIndices: []
|
|
283
|
-
}
|
|
384
|
+
};
|
|
284
385
|
if (account.role === AccountRole.WRITABLE) {
|
|
285
386
|
entry.writableIndices.push(account.addressIndex);
|
|
286
387
|
} else {
|
|
287
388
|
entry.readableIndices.push(account.addressIndex);
|
|
288
389
|
}
|
|
289
390
|
}
|
|
290
|
-
return Object.keys(index).sort(
|
|
391
|
+
return Object.keys(index).sort(addresses.getAddressComparator()).map((lookupTableAddress) => ({
|
|
291
392
|
lookupTableAddress,
|
|
292
393
|
...index[lookupTableAddress]
|
|
293
394
|
}));
|
|
@@ -366,151 +467,189 @@ function compileMessage(transaction) {
|
|
|
366
467
|
version: transaction.version
|
|
367
468
|
};
|
|
368
469
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
470
|
+
var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
|
|
471
|
+
var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
|
|
472
|
+
var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
|
|
473
|
+
var addressTableLookupDescription = __DEV__ ? "A pointer to the address of an address lookup table, along with the readonly/writeable indices of the addresses that should be loaded from it" : "addressTableLookup";
|
|
474
|
+
var memoizedAddressTableLookupEncoder;
|
|
475
|
+
function getAddressTableLookupEncoder() {
|
|
476
|
+
if (!memoizedAddressTableLookupEncoder) {
|
|
477
|
+
memoizedAddressTableLookupEncoder = codecsDataStructures.getStructEncoder(
|
|
372
478
|
[
|
|
373
|
-
"lookupTableAddress",
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
479
|
+
["lookupTableAddress", addresses.getAddressEncoder({ description: lookupTableAddressDescription })],
|
|
480
|
+
[
|
|
481
|
+
"writableIndices",
|
|
482
|
+
codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), {
|
|
483
|
+
description: writableIndicesDescription,
|
|
484
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
485
|
+
})
|
|
486
|
+
],
|
|
487
|
+
[
|
|
488
|
+
"readableIndices",
|
|
489
|
+
codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), {
|
|
490
|
+
description: readableIndicesDescription,
|
|
491
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
492
|
+
})
|
|
493
|
+
]
|
|
379
494
|
],
|
|
495
|
+
{ description: addressTableLookupDescription }
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
return memoizedAddressTableLookupEncoder;
|
|
499
|
+
}
|
|
500
|
+
var memoizedAddressTableLookupDecoder;
|
|
501
|
+
function getAddressTableLookupDecoder() {
|
|
502
|
+
if (!memoizedAddressTableLookupDecoder) {
|
|
503
|
+
memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder(
|
|
380
504
|
[
|
|
381
|
-
"
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
505
|
+
["lookupTableAddress", addresses.getAddressDecoder({ description: lookupTableAddressDescription })],
|
|
506
|
+
[
|
|
507
|
+
"writableIndices",
|
|
508
|
+
codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
|
|
509
|
+
description: writableIndicesDescription,
|
|
510
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
511
|
+
})
|
|
512
|
+
],
|
|
513
|
+
[
|
|
514
|
+
"readableIndices",
|
|
515
|
+
codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
|
|
516
|
+
description: readableIndicesDescription,
|
|
517
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
518
|
+
})
|
|
519
|
+
]
|
|
388
520
|
],
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
521
|
+
{ description: addressTableLookupDescription }
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
return memoizedAddressTableLookupDecoder;
|
|
525
|
+
}
|
|
526
|
+
var memoizedU8Encoder;
|
|
527
|
+
function getMemoizedU8Encoder() {
|
|
528
|
+
if (!memoizedU8Encoder)
|
|
529
|
+
memoizedU8Encoder = codecsNumbers.getU8Encoder();
|
|
530
|
+
return memoizedU8Encoder;
|
|
531
|
+
}
|
|
532
|
+
function getMemoizedU8EncoderDescription(description) {
|
|
533
|
+
const encoder = getMemoizedU8Encoder();
|
|
534
|
+
return {
|
|
535
|
+
...encoder,
|
|
536
|
+
description: description ?? encoder.description
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
var memoizedU8Decoder;
|
|
540
|
+
function getMemoizedU8Decoder() {
|
|
541
|
+
if (!memoizedU8Decoder)
|
|
542
|
+
memoizedU8Decoder = codecsNumbers.getU8Decoder();
|
|
543
|
+
return memoizedU8Decoder;
|
|
544
|
+
}
|
|
545
|
+
function getMemoizedU8DecoderDescription(description) {
|
|
546
|
+
const decoder = getMemoizedU8Decoder();
|
|
547
|
+
return {
|
|
548
|
+
...decoder,
|
|
549
|
+
description: description ?? decoder.description
|
|
550
|
+
};
|
|
403
551
|
}
|
|
404
|
-
|
|
405
|
-
|
|
552
|
+
var numSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction" : void 0;
|
|
553
|
+
var numReadonlySignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction, but may not be writable" : void 0;
|
|
554
|
+
var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
|
|
555
|
+
var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
|
|
556
|
+
function getMessageHeaderEncoder() {
|
|
557
|
+
return codecsDataStructures.getStructEncoder(
|
|
406
558
|
[
|
|
407
|
-
[
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
__DEV__ ? {
|
|
411
|
-
description: "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction"
|
|
412
|
-
} : void 0
|
|
413
|
-
)
|
|
414
|
-
],
|
|
415
|
-
[
|
|
416
|
-
"numReadonlySignerAccounts",
|
|
417
|
-
umiSerializers.u8(
|
|
418
|
-
__DEV__ ? {
|
|
419
|
-
description: "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction, but may not be writable"
|
|
420
|
-
} : void 0
|
|
421
|
-
)
|
|
422
|
-
],
|
|
423
|
-
[
|
|
424
|
-
"numReadonlyNonSignerAccounts",
|
|
425
|
-
umiSerializers.u8(
|
|
426
|
-
__DEV__ ? {
|
|
427
|
-
description: "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable"
|
|
428
|
-
} : void 0
|
|
429
|
-
)
|
|
430
|
-
]
|
|
559
|
+
["numSignerAccounts", getMemoizedU8EncoderDescription(numSignerAccountsDescription)],
|
|
560
|
+
["numReadonlySignerAccounts", getMemoizedU8EncoderDescription(numReadonlySignerAccountsDescription)],
|
|
561
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8EncoderDescription(numReadonlyNonSignerAccountsDescription)]
|
|
431
562
|
],
|
|
432
|
-
|
|
433
|
-
description:
|
|
434
|
-
}
|
|
563
|
+
{
|
|
564
|
+
description: messageHeaderDescription
|
|
565
|
+
}
|
|
435
566
|
);
|
|
436
567
|
}
|
|
437
|
-
function
|
|
438
|
-
return
|
|
439
|
-
|
|
440
|
-
[
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
)
|
|
447
|
-
],
|
|
448
|
-
[
|
|
449
|
-
"addressIndices",
|
|
450
|
-
umiSerializers.array(
|
|
451
|
-
umiSerializers.u8({
|
|
452
|
-
description: __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : ""
|
|
453
|
-
}),
|
|
454
|
-
{
|
|
455
|
-
description: __DEV__ ? "An optional list of account indices, according to the well-ordered accounts list for this transaction, in the order in which the program being called expects them" : "",
|
|
456
|
-
size: umiSerializers.shortU16()
|
|
457
|
-
}
|
|
458
|
-
)
|
|
459
|
-
],
|
|
460
|
-
[
|
|
461
|
-
"data",
|
|
462
|
-
umiSerializers.bytes({
|
|
463
|
-
description: __DEV__ ? "An optional buffer of data passed to the instruction" : "",
|
|
464
|
-
size: umiSerializers.shortU16()
|
|
465
|
-
})
|
|
466
|
-
]
|
|
467
|
-
]),
|
|
468
|
-
(value) => {
|
|
469
|
-
if (value.addressIndices !== void 0 && value.data !== void 0) {
|
|
470
|
-
return value;
|
|
471
|
-
}
|
|
472
|
-
return {
|
|
473
|
-
...value,
|
|
474
|
-
addressIndices: value.addressIndices ?? [],
|
|
475
|
-
data: value.data ?? new Uint8Array(0)
|
|
476
|
-
};
|
|
477
|
-
},
|
|
478
|
-
(value) => {
|
|
479
|
-
if (value.addressIndices.length && value.data.byteLength) {
|
|
480
|
-
return value;
|
|
481
|
-
}
|
|
482
|
-
const { addressIndices, data, ...rest } = value;
|
|
483
|
-
return {
|
|
484
|
-
...rest,
|
|
485
|
-
...addressIndices.length ? { addressIndices } : null,
|
|
486
|
-
...data.byteLength ? { data } : null
|
|
487
|
-
};
|
|
568
|
+
function getMessageHeaderDecoder() {
|
|
569
|
+
return codecsDataStructures.getStructDecoder(
|
|
570
|
+
[
|
|
571
|
+
["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
|
|
572
|
+
["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
|
|
573
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
|
|
574
|
+
],
|
|
575
|
+
{
|
|
576
|
+
description: messageHeaderDescription
|
|
488
577
|
}
|
|
489
578
|
);
|
|
490
579
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
)
|
|
580
|
+
var programAddressIndexDescription = __DEV__ ? "The index of the program being called, according to the well-ordered accounts list for this transaction" : "programAddressIndex";
|
|
581
|
+
var accountIndexDescription = __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : void 0;
|
|
582
|
+
var accountIndicesDescription = __DEV__ ? "An optional list of account indices, according to the well-ordered accounts list for this transaction, in the order in which the program being called expects them" : "accountIndices";
|
|
583
|
+
var dataDescription = __DEV__ ? "An optional buffer of data passed to the instruction" : "data";
|
|
584
|
+
var memoizedGetInstructionEncoder;
|
|
585
|
+
function getInstructionEncoder() {
|
|
586
|
+
if (!memoizedGetInstructionEncoder) {
|
|
587
|
+
memoizedGetInstructionEncoder = codecsCore.mapEncoder(
|
|
588
|
+
codecsDataStructures.getStructEncoder([
|
|
589
|
+
["programAddressIndex", codecsNumbers.getU8Encoder({ description: programAddressIndexDescription })],
|
|
590
|
+
[
|
|
591
|
+
"accountIndices",
|
|
592
|
+
codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder({ description: accountIndexDescription }), {
|
|
593
|
+
description: accountIndicesDescription,
|
|
594
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
595
|
+
})
|
|
596
|
+
],
|
|
597
|
+
["data", codecsDataStructures.getBytesEncoder({ description: dataDescription, size: codecsNumbers.getShortU16Encoder() })]
|
|
598
|
+
]),
|
|
599
|
+
// Convert an instruction to have all fields defined
|
|
600
|
+
(instruction) => {
|
|
601
|
+
if (instruction.accountIndices !== void 0 && instruction.data !== void 0) {
|
|
602
|
+
return instruction;
|
|
603
|
+
}
|
|
604
|
+
return {
|
|
605
|
+
...instruction,
|
|
606
|
+
accountIndices: instruction.accountIndices ?? [],
|
|
607
|
+
data: instruction.data ?? new Uint8Array(0)
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
return memoizedGetInstructionEncoder;
|
|
498
613
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
614
|
+
var memoizedGetInstructionDecoder;
|
|
615
|
+
function getInstructionDecoder() {
|
|
616
|
+
if (!memoizedGetInstructionDecoder) {
|
|
617
|
+
memoizedGetInstructionDecoder = codecsCore.mapDecoder(
|
|
618
|
+
codecsDataStructures.getStructDecoder([
|
|
619
|
+
["programAddressIndex", codecsNumbers.getU8Decoder({ description: programAddressIndexDescription })],
|
|
620
|
+
[
|
|
621
|
+
"accountIndices",
|
|
622
|
+
codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder({ description: accountIndexDescription }), {
|
|
623
|
+
description: accountIndicesDescription,
|
|
624
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
625
|
+
})
|
|
626
|
+
],
|
|
627
|
+
["data", codecsDataStructures.getBytesDecoder({ description: dataDescription, size: codecsNumbers.getShortU16Decoder() })]
|
|
628
|
+
]),
|
|
629
|
+
// Convert an instruction to exclude optional fields if they are empty
|
|
630
|
+
(instruction) => {
|
|
631
|
+
if (instruction.accountIndices.length && instruction.data.byteLength) {
|
|
632
|
+
return instruction;
|
|
633
|
+
}
|
|
634
|
+
const { accountIndices, data, ...rest } = instruction;
|
|
635
|
+
return {
|
|
636
|
+
...rest,
|
|
637
|
+
...accountIndices.length ? { accountIndices } : null,
|
|
638
|
+
...data.byteLength ? { data } : null
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
return memoizedGetInstructionDecoder;
|
|
503
644
|
}
|
|
504
|
-
|
|
505
|
-
// src/serializers/transaction-version.ts
|
|
506
645
|
var VERSION_FLAG_MASK = 128;
|
|
507
646
|
var BASE_CONFIG = {
|
|
508
647
|
description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
|
|
509
648
|
fixedSize: null,
|
|
510
649
|
maxSize: 1
|
|
511
650
|
};
|
|
512
|
-
function
|
|
513
|
-
const firstByte =
|
|
651
|
+
function decode(bytes, offset = 0) {
|
|
652
|
+
const firstByte = bytes[offset];
|
|
514
653
|
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
515
654
|
return ["legacy", offset];
|
|
516
655
|
} else {
|
|
@@ -518,7 +657,7 @@ function deserialize(bytes3, offset = 0) {
|
|
|
518
657
|
return [version, offset + 1];
|
|
519
658
|
}
|
|
520
659
|
}
|
|
521
|
-
function
|
|
660
|
+
function encode(value) {
|
|
522
661
|
if (value === "legacy") {
|
|
523
662
|
return new Uint8Array();
|
|
524
663
|
}
|
|
@@ -527,105 +666,143 @@ function serialize(value) {
|
|
|
527
666
|
}
|
|
528
667
|
return new Uint8Array([value | VERSION_FLAG_MASK]);
|
|
529
668
|
}
|
|
530
|
-
function
|
|
669
|
+
function getTransactionVersionDecoder() {
|
|
531
670
|
return {
|
|
532
671
|
...BASE_CONFIG,
|
|
533
|
-
|
|
534
|
-
|
|
672
|
+
decode
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
function getTransactionVersionEncoder() {
|
|
676
|
+
return {
|
|
677
|
+
...BASE_CONFIG,
|
|
678
|
+
encode
|
|
535
679
|
};
|
|
536
680
|
}
|
|
537
681
|
|
|
538
682
|
// src/serializers/message.ts
|
|
539
|
-
var
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
(value)
|
|
554
|
-
|
|
555
|
-
return value;
|
|
556
|
-
}
|
|
557
|
-
return {
|
|
558
|
-
...value,
|
|
559
|
-
addressTableLookups: value.addressTableLookups ?? []
|
|
560
|
-
};
|
|
683
|
+
var staticAccountsDescription = __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "staticAccounts";
|
|
684
|
+
var lifetimeTokenDescription = __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "lifetimeToken";
|
|
685
|
+
var instructionsDescription = __DEV__ ? "A compact-array of instructions belonging to this transaction" : "instructions";
|
|
686
|
+
var addressTableLookupsDescription = __DEV__ ? "A compact array of address table lookups belonging to this transaction" : "addressTableLookups";
|
|
687
|
+
function getCompiledMessageLegacyEncoder() {
|
|
688
|
+
return codecsDataStructures.getStructEncoder(getPreludeStructEncoderTuple());
|
|
689
|
+
}
|
|
690
|
+
function getCompiledMessageVersionedEncoder() {
|
|
691
|
+
return codecsCore.mapEncoder(
|
|
692
|
+
codecsDataStructures.getStructEncoder([
|
|
693
|
+
...getPreludeStructEncoderTuple(),
|
|
694
|
+
["addressTableLookups", getAddressTableLookupArrayEncoder()]
|
|
695
|
+
]),
|
|
696
|
+
(value) => {
|
|
697
|
+
if (value.version === "legacy") {
|
|
698
|
+
return value;
|
|
561
699
|
}
|
|
562
|
-
|
|
563
|
-
|
|
700
|
+
return {
|
|
701
|
+
...value,
|
|
702
|
+
addressTableLookups: value.addressTableLookups ?? []
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
);
|
|
564
706
|
}
|
|
565
|
-
function
|
|
707
|
+
function getPreludeStructEncoderTuple() {
|
|
566
708
|
return [
|
|
567
|
-
["version",
|
|
568
|
-
["header",
|
|
709
|
+
["version", getTransactionVersionEncoder()],
|
|
710
|
+
["header", getMessageHeaderEncoder()],
|
|
569
711
|
[
|
|
570
712
|
"staticAccounts",
|
|
571
|
-
|
|
572
|
-
description:
|
|
573
|
-
size:
|
|
713
|
+
codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), {
|
|
714
|
+
description: staticAccountsDescription,
|
|
715
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
574
716
|
})
|
|
575
717
|
],
|
|
576
718
|
[
|
|
577
719
|
"lifetimeToken",
|
|
578
|
-
|
|
579
|
-
description:
|
|
580
|
-
encoding:
|
|
720
|
+
codecsStrings.getStringEncoder({
|
|
721
|
+
description: lifetimeTokenDescription,
|
|
722
|
+
encoding: codecsStrings.getBase58Encoder(),
|
|
581
723
|
size: 32
|
|
582
724
|
})
|
|
583
725
|
],
|
|
584
726
|
[
|
|
585
727
|
"instructions",
|
|
586
|
-
|
|
587
|
-
description:
|
|
588
|
-
size:
|
|
728
|
+
codecsDataStructures.getArrayEncoder(getInstructionEncoder(), {
|
|
729
|
+
description: instructionsDescription,
|
|
730
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
589
731
|
})
|
|
590
732
|
]
|
|
591
733
|
];
|
|
592
734
|
}
|
|
593
|
-
function
|
|
594
|
-
return
|
|
595
|
-
|
|
596
|
-
|
|
735
|
+
function getPreludeStructDecoderTuple() {
|
|
736
|
+
return [
|
|
737
|
+
["version", getTransactionVersionDecoder()],
|
|
738
|
+
["header", getMessageHeaderDecoder()],
|
|
739
|
+
[
|
|
740
|
+
"staticAccounts",
|
|
741
|
+
codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), {
|
|
742
|
+
description: staticAccountsDescription,
|
|
743
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
744
|
+
})
|
|
745
|
+
],
|
|
746
|
+
[
|
|
747
|
+
"lifetimeToken",
|
|
748
|
+
codecsStrings.getStringDecoder({
|
|
749
|
+
description: lifetimeTokenDescription,
|
|
750
|
+
encoding: codecsStrings.getBase58Decoder(),
|
|
751
|
+
size: 32
|
|
752
|
+
})
|
|
753
|
+
],
|
|
754
|
+
[
|
|
755
|
+
"instructions",
|
|
756
|
+
codecsDataStructures.getArrayDecoder(getInstructionDecoder(), {
|
|
757
|
+
description: instructionsDescription,
|
|
758
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
759
|
+
})
|
|
760
|
+
],
|
|
761
|
+
["addressTableLookups", getAddressTableLookupArrayDecoder()]
|
|
762
|
+
];
|
|
763
|
+
}
|
|
764
|
+
function getAddressTableLookupArrayEncoder() {
|
|
765
|
+
return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), {
|
|
766
|
+
description: addressTableLookupsDescription,
|
|
767
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
597
768
|
});
|
|
598
769
|
}
|
|
770
|
+
function getAddressTableLookupArrayDecoder() {
|
|
771
|
+
return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
|
|
772
|
+
description: addressTableLookupsDescription,
|
|
773
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
|
|
599
777
|
function getCompiledMessageEncoder() {
|
|
600
778
|
return {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
779
|
+
description: messageDescription,
|
|
780
|
+
encode: (compiledMessage) => {
|
|
781
|
+
if (compiledMessage.version === "legacy") {
|
|
782
|
+
return getCompiledMessageLegacyEncoder().encode(compiledMessage);
|
|
783
|
+
} else {
|
|
784
|
+
return getCompiledMessageVersionedEncoder().encode(compiledMessage);
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
fixedSize: null,
|
|
788
|
+
maxSize: null
|
|
604
789
|
};
|
|
605
790
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
791
|
+
function getCompiledMessageDecoder() {
|
|
792
|
+
return codecsCore.mapDecoder(
|
|
793
|
+
codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple(), {
|
|
794
|
+
description: messageDescription
|
|
795
|
+
}),
|
|
796
|
+
({ addressTableLookups, ...restOfMessage }) => {
|
|
797
|
+
if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
|
|
798
|
+
return restOfMessage;
|
|
799
|
+
}
|
|
800
|
+
return { ...restOfMessage, addressTableLookups };
|
|
801
|
+
}
|
|
802
|
+
);
|
|
612
803
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
const [signerPublicKey, signature] = await Promise.all([
|
|
616
|
-
keys.getBase58EncodedAddressFromPublicKey(keyPair.publicKey),
|
|
617
|
-
getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
|
|
618
|
-
]);
|
|
619
|
-
const nextSignatures = {
|
|
620
|
-
..."signatures" in transaction ? transaction.signatures : null,
|
|
621
|
-
...{ [signerPublicKey]: signature }
|
|
622
|
-
};
|
|
623
|
-
const out = {
|
|
624
|
-
...transaction,
|
|
625
|
-
signatures: nextSignatures
|
|
626
|
-
};
|
|
627
|
-
Object.freeze(out);
|
|
628
|
-
return out;
|
|
804
|
+
function getCompiledMessageCodec() {
|
|
805
|
+
return codecsCore.combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
|
|
629
806
|
}
|
|
630
807
|
|
|
631
808
|
// src/compile-transaction.ts
|
|
@@ -645,47 +822,239 @@ function getCompiledTransaction(transaction) {
|
|
|
645
822
|
signatures
|
|
646
823
|
};
|
|
647
824
|
}
|
|
825
|
+
function getAccountMetas(message) {
|
|
826
|
+
const { header } = message;
|
|
827
|
+
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
828
|
+
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
829
|
+
const accountMetas = [];
|
|
830
|
+
let accountIndex = 0;
|
|
831
|
+
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
832
|
+
accountMetas.push({
|
|
833
|
+
address: message.staticAccounts[accountIndex],
|
|
834
|
+
role: AccountRole.WRITABLE_SIGNER
|
|
835
|
+
});
|
|
836
|
+
accountIndex++;
|
|
837
|
+
}
|
|
838
|
+
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
839
|
+
accountMetas.push({
|
|
840
|
+
address: message.staticAccounts[accountIndex],
|
|
841
|
+
role: AccountRole.READONLY_SIGNER
|
|
842
|
+
});
|
|
843
|
+
accountIndex++;
|
|
844
|
+
}
|
|
845
|
+
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
846
|
+
accountMetas.push({
|
|
847
|
+
address: message.staticAccounts[accountIndex],
|
|
848
|
+
role: AccountRole.WRITABLE
|
|
849
|
+
});
|
|
850
|
+
accountIndex++;
|
|
851
|
+
}
|
|
852
|
+
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
853
|
+
accountMetas.push({
|
|
854
|
+
address: message.staticAccounts[accountIndex],
|
|
855
|
+
role: AccountRole.READONLY
|
|
856
|
+
});
|
|
857
|
+
accountIndex++;
|
|
858
|
+
}
|
|
859
|
+
return accountMetas;
|
|
860
|
+
}
|
|
861
|
+
function convertInstruction(instruction, accountMetas) {
|
|
862
|
+
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
863
|
+
if (!programAddress) {
|
|
864
|
+
throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
|
|
865
|
+
}
|
|
866
|
+
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
867
|
+
const { data } = instruction;
|
|
868
|
+
return {
|
|
869
|
+
programAddress,
|
|
870
|
+
...accounts && accounts.length ? { accounts } : {},
|
|
871
|
+
...data && data.length ? { data } : {}
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
875
|
+
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
876
|
+
return {
|
|
877
|
+
blockhash: messageLifetimeToken,
|
|
878
|
+
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
879
|
+
// U64 MAX
|
|
880
|
+
};
|
|
881
|
+
} else {
|
|
882
|
+
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
883
|
+
addresses.assertIsAddress(nonceAccountAddress);
|
|
884
|
+
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
885
|
+
addresses.assertIsAddress(nonceAuthorityAddress);
|
|
886
|
+
return {
|
|
887
|
+
nonce: messageLifetimeToken,
|
|
888
|
+
nonceAccountAddress,
|
|
889
|
+
nonceAuthorityAddress
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
function convertSignatures(compiledTransaction) {
|
|
894
|
+
const {
|
|
895
|
+
compiledMessage: { staticAccounts },
|
|
896
|
+
signatures
|
|
897
|
+
} = compiledTransaction;
|
|
898
|
+
return signatures.reduce((acc, sig, index) => {
|
|
899
|
+
const allZeros = sig.every((byte) => byte === 0);
|
|
900
|
+
if (allZeros)
|
|
901
|
+
return acc;
|
|
902
|
+
const address = staticAccounts[index];
|
|
903
|
+
return { ...acc, [address]: sig };
|
|
904
|
+
}, {});
|
|
905
|
+
}
|
|
906
|
+
function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
|
|
907
|
+
const { compiledMessage } = compiledTransaction;
|
|
908
|
+
if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
|
|
909
|
+
throw new Error("Cannot convert transaction with addressTableLookups");
|
|
910
|
+
}
|
|
911
|
+
const feePayer = compiledMessage.staticAccounts[0];
|
|
912
|
+
if (!feePayer)
|
|
913
|
+
throw new Error("No fee payer set in CompiledTransaction");
|
|
914
|
+
const accountMetas = getAccountMetas(compiledMessage);
|
|
915
|
+
const instructions = compiledMessage.instructions.map(
|
|
916
|
+
(compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
|
|
917
|
+
);
|
|
918
|
+
const firstInstruction = instructions[0];
|
|
919
|
+
const lifetimeConstraint = getLifetimeConstraint(
|
|
920
|
+
compiledMessage.lifetimeToken,
|
|
921
|
+
firstInstruction,
|
|
922
|
+
lastValidBlockHeight
|
|
923
|
+
);
|
|
924
|
+
const signatures = convertSignatures(compiledTransaction);
|
|
925
|
+
return functional.pipe(
|
|
926
|
+
createTransaction({ version: compiledMessage.version }),
|
|
927
|
+
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
928
|
+
(tx) => instructions.reduce((acc, instruction) => {
|
|
929
|
+
return appendTransactionInstruction(instruction, acc);
|
|
930
|
+
}, tx),
|
|
931
|
+
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
932
|
+
(tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
|
|
933
|
+
);
|
|
934
|
+
}
|
|
648
935
|
|
|
649
936
|
// src/serializers/transaction.ts
|
|
650
|
-
var
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
};
|
|
655
|
-
function serialize3(transaction) {
|
|
656
|
-
const compiledTransaction = getCompiledTransaction(transaction);
|
|
657
|
-
return umiSerializers.struct([
|
|
937
|
+
var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
|
|
938
|
+
var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
|
|
939
|
+
function getCompiledTransactionEncoder() {
|
|
940
|
+
return codecsDataStructures.getStructEncoder(
|
|
658
941
|
[
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
942
|
+
[
|
|
943
|
+
"signatures",
|
|
944
|
+
codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), {
|
|
945
|
+
description: signaturesDescription,
|
|
946
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
947
|
+
})
|
|
948
|
+
],
|
|
949
|
+
["compiledMessage", getCompiledMessageEncoder()]
|
|
950
|
+
],
|
|
951
|
+
{
|
|
952
|
+
description: transactionDescription
|
|
953
|
+
}
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
function getSignatureDecoder() {
|
|
957
|
+
return codecsCore.mapDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), (bytes) => bytes);
|
|
958
|
+
}
|
|
959
|
+
function getCompiledTransactionDecoder() {
|
|
960
|
+
return codecsDataStructures.getStructDecoder(
|
|
961
|
+
[
|
|
962
|
+
[
|
|
963
|
+
"signatures",
|
|
964
|
+
codecsDataStructures.getArrayDecoder(getSignatureDecoder(), {
|
|
965
|
+
description: signaturesDescription,
|
|
966
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
967
|
+
})
|
|
968
|
+
],
|
|
969
|
+
["compiledMessage", getCompiledMessageDecoder()]
|
|
664
970
|
],
|
|
665
|
-
|
|
666
|
-
|
|
971
|
+
{
|
|
972
|
+
description: transactionDescription
|
|
973
|
+
}
|
|
974
|
+
);
|
|
667
975
|
}
|
|
668
976
|
function getTransactionEncoder() {
|
|
669
|
-
return
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
977
|
+
return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
|
|
978
|
+
}
|
|
979
|
+
function getTransactionDecoder(lastValidBlockHeight) {
|
|
980
|
+
return codecsCore.mapDecoder(
|
|
981
|
+
getCompiledTransactionDecoder(),
|
|
982
|
+
(compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
|
|
983
|
+
);
|
|
984
|
+
}
|
|
985
|
+
function getTransactionCodec(lastValidBlockHeight) {
|
|
986
|
+
return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
|
|
987
|
+
}
|
|
988
|
+
var base58Decoder;
|
|
989
|
+
function getSignatureFromTransaction(transaction) {
|
|
990
|
+
if (!base58Decoder)
|
|
991
|
+
base58Decoder = codecsStrings.getBase58Decoder();
|
|
992
|
+
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
993
|
+
if (!signatureBytes) {
|
|
994
|
+
throw new Error(
|
|
995
|
+
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
const transactionSignature = base58Decoder.decode(signatureBytes)[0];
|
|
999
|
+
return transactionSignature;
|
|
1000
|
+
}
|
|
1001
|
+
async function partiallySignTransaction(keyPairs, transaction) {
|
|
1002
|
+
const compiledMessage = compileMessage(transaction);
|
|
1003
|
+
const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
|
|
1004
|
+
const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
|
|
1005
|
+
const publicKeySignaturePairs = await Promise.all(
|
|
1006
|
+
keyPairs.map(
|
|
1007
|
+
(keyPair) => Promise.all([addresses.getAddressFromPublicKey(keyPair.publicKey), keys.signBytes(keyPair.privateKey, wireMessageBytes)])
|
|
1008
|
+
)
|
|
1009
|
+
);
|
|
1010
|
+
for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
|
|
1011
|
+
nextSignatures[signerPublicKey] = signature;
|
|
1012
|
+
}
|
|
1013
|
+
const out = {
|
|
1014
|
+
...transaction,
|
|
1015
|
+
signatures: nextSignatures
|
|
673
1016
|
};
|
|
1017
|
+
Object.freeze(out);
|
|
1018
|
+
return out;
|
|
1019
|
+
}
|
|
1020
|
+
async function signTransaction(keyPairs, transaction) {
|
|
1021
|
+
const out = await partiallySignTransaction(keyPairs, transaction);
|
|
1022
|
+
assertTransactionIsFullySigned(out);
|
|
1023
|
+
Object.freeze(out);
|
|
1024
|
+
return out;
|
|
1025
|
+
}
|
|
1026
|
+
function assertTransactionIsFullySigned(transaction) {
|
|
1027
|
+
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
|
|
1028
|
+
const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
|
|
1029
|
+
requiredSigners.forEach((address) => {
|
|
1030
|
+
if (!transaction.signatures[address]) {
|
|
1031
|
+
throw new Error(`Transaction is missing signature for address \`${address}\``);
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
674
1034
|
}
|
|
675
|
-
|
|
676
|
-
// src/wire-transaction.ts
|
|
677
1035
|
function getBase64EncodedWireTransaction(transaction) {
|
|
678
|
-
const wireTransactionBytes = getTransactionEncoder().
|
|
679
|
-
|
|
680
|
-
return btoa(String.fromCharCode(...wireTransactionBytes));
|
|
681
|
-
}
|
|
1036
|
+
const wireTransactionBytes = getTransactionEncoder().encode(transaction);
|
|
1037
|
+
return codecsStrings.getBase64Decoder().decode(wireTransactionBytes)[0];
|
|
682
1038
|
}
|
|
683
1039
|
|
|
684
1040
|
exports.appendTransactionInstruction = appendTransactionInstruction;
|
|
1041
|
+
exports.assertIsBlockhash = assertIsBlockhash;
|
|
1042
|
+
exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
|
|
1043
|
+
exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
|
|
1044
|
+
exports.compileMessage = compileMessage;
|
|
685
1045
|
exports.createTransaction = createTransaction;
|
|
686
1046
|
exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
|
|
1047
|
+
exports.getCompiledMessageCodec = getCompiledMessageCodec;
|
|
1048
|
+
exports.getCompiledMessageDecoder = getCompiledMessageDecoder;
|
|
1049
|
+
exports.getCompiledMessageEncoder = getCompiledMessageEncoder;
|
|
1050
|
+
exports.getSignatureFromTransaction = getSignatureFromTransaction;
|
|
1051
|
+
exports.getTransactionCodec = getTransactionCodec;
|
|
1052
|
+
exports.getTransactionDecoder = getTransactionDecoder;
|
|
1053
|
+
exports.getTransactionEncoder = getTransactionEncoder;
|
|
1054
|
+
exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
|
|
1055
|
+
exports.partiallySignTransaction = partiallySignTransaction;
|
|
687
1056
|
exports.prependTransactionInstruction = prependTransactionInstruction;
|
|
688
1057
|
exports.setTransactionFeePayer = setTransactionFeePayer;
|
|
1058
|
+
exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
|
|
1059
|
+
exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
|
|
689
1060
|
exports.signTransaction = signTransaction;
|
|
690
|
-
//# sourceMappingURL=out.js.map
|
|
691
|
-
//# sourceMappingURL=index.browser.cjs.map
|