@solana/transactions 2.0.0-experimental.e4483d3 → 2.0.0-experimental.e587f8d
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/README.md +7 -3
- package/dist/index.browser.cjs +322 -394
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +323 -398
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +323 -398
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +322 -394
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +323 -398
- package/dist/index.node.js.map +1 -1
- package/dist/types/accounts.d.ts.map +1 -1
- package/dist/types/blockhash.d.ts +5 -7
- package/dist/types/blockhash.d.ts.map +1 -1
- package/dist/types/compilable-transaction.d.ts +4 -4
- package/dist/types/compile-address-table-lookups.d.ts +1 -1
- package/dist/types/compile-header.d.ts +1 -1
- package/dist/types/compile-instructions.d.ts +1 -1
- package/dist/types/compile-lifetime-token.d.ts +1 -1
- package/dist/types/compile-static-accounts.d.ts +1 -1
- package/dist/types/compile-transaction.d.ts +3 -3
- package/dist/types/create-transaction.d.ts +1 -1
- package/dist/types/decompile-transaction.d.ts +12 -4
- package/dist/types/decompile-transaction.d.ts.map +1 -1
- package/dist/types/durable-nonce.d.ts +2 -2
- package/dist/types/durable-nonce.d.ts.map +1 -1
- package/dist/types/fee-payer.d.ts +2 -2
- package/dist/types/index.d.ts +13 -11
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/instructions.d.ts +4 -2
- package/dist/types/instructions.d.ts.map +1 -1
- package/dist/types/message.d.ts +6 -6
- package/dist/types/serializers/address-table-lookup.d.ts +5 -5
- package/dist/types/serializers/address-table-lookup.d.ts.map +1 -1
- package/dist/types/serializers/header.d.ts +5 -5
- package/dist/types/serializers/header.d.ts.map +1 -1
- package/dist/types/serializers/index.d.ts +2 -2
- package/dist/types/serializers/instruction.d.ts +5 -5
- package/dist/types/serializers/instruction.d.ts.map +1 -1
- package/dist/types/serializers/message.d.ts +5 -5
- package/dist/types/serializers/message.d.ts.map +1 -1
- package/dist/types/serializers/transaction-version.d.ts +5 -5
- package/dist/types/serializers/transaction-version.d.ts.map +1 -1
- package/dist/types/serializers/transaction.d.ts +9 -6
- package/dist/types/serializers/transaction.d.ts.map +1 -1
- package/dist/types/signatures.d.ts +2 -2
- package/dist/types/signatures.d.ts.map +1 -1
- package/dist/types/unsigned-transaction.d.ts +1 -1
- package/dist/types/wire-transaction.d.ts +1 -1
- package/package.json +18 -39
- package/dist/index.development.js +0 -1783
- package/dist/index.development.js.map +0 -1
- package/dist/index.production.min.js +0 -31
package/dist/index.browser.cjs
CHANGED
|
@@ -1,15 +1,36 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var errors = require('@solana/errors');
|
|
3
4
|
var codecsStrings = require('@solana/codecs-strings');
|
|
4
5
|
var addresses = require('@solana/addresses');
|
|
6
|
+
var functional = require('@solana/functional');
|
|
5
7
|
var codecsCore = require('@solana/codecs-core');
|
|
6
8
|
var codecsDataStructures = require('@solana/codecs-data-structures');
|
|
7
9
|
var codecsNumbers = require('@solana/codecs-numbers');
|
|
8
|
-
var functional = require('@solana/functional');
|
|
9
10
|
var keys = require('@solana/keys');
|
|
10
11
|
|
|
11
|
-
//
|
|
12
|
-
var
|
|
12
|
+
// src/blockhash.ts
|
|
13
|
+
var base58Encoder;
|
|
14
|
+
function assertIsBlockhash(putativeBlockhash) {
|
|
15
|
+
if (!base58Encoder)
|
|
16
|
+
base58Encoder = codecsStrings.getBase58Encoder();
|
|
17
|
+
if (
|
|
18
|
+
// Lowest value (32 bytes of zeroes)
|
|
19
|
+
putativeBlockhash.length < 32 || // Highest value (32 bytes of 255)
|
|
20
|
+
putativeBlockhash.length > 44
|
|
21
|
+
) {
|
|
22
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE, {
|
|
23
|
+
actualLength: putativeBlockhash.length
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const bytes = base58Encoder.encode(putativeBlockhash);
|
|
27
|
+
const numBytes = bytes.byteLength;
|
|
28
|
+
if (numBytes !== 32) {
|
|
29
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH, {
|
|
30
|
+
actualLength: numBytes
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
13
34
|
|
|
14
35
|
// src/unsigned-transaction.ts
|
|
15
36
|
function getUnsignedTransaction(transaction) {
|
|
@@ -26,27 +47,20 @@ function getUnsignedTransaction(transaction) {
|
|
|
26
47
|
}
|
|
27
48
|
|
|
28
49
|
// src/blockhash.ts
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (!
|
|
32
|
-
|
|
50
|
+
function isTransactionWithBlockhashLifetime(transaction) {
|
|
51
|
+
const lifetimeConstraintShapeMatches = "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.blockhash === "string" && typeof transaction.lifetimeConstraint.lastValidBlockHeight === "bigint";
|
|
52
|
+
if (!lifetimeConstraintShapeMatches)
|
|
53
|
+
return false;
|
|
33
54
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
});
|
|
55
|
+
assertIsBlockhash(transaction.lifetimeConstraint.blockhash);
|
|
56
|
+
return true;
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function assertIsTransactionWithBlockhashLifetime(transaction) {
|
|
62
|
+
if (!isTransactionWithBlockhashLifetime(transaction)) {
|
|
63
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME);
|
|
50
64
|
}
|
|
51
65
|
}
|
|
52
66
|
function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
|
|
@@ -72,8 +86,6 @@ function createTransaction({
|
|
|
72
86
|
Object.freeze(out);
|
|
73
87
|
return out;
|
|
74
88
|
}
|
|
75
|
-
|
|
76
|
-
// ../instructions/dist/index.browser.js
|
|
77
89
|
var AccountRole = /* @__PURE__ */ ((AccountRole2) => {
|
|
78
90
|
AccountRole2[AccountRole2["WRITABLE_SIGNER"] = /* 3 */
|
|
79
91
|
3] = "WRITABLE_SIGNER";
|
|
@@ -95,13 +107,11 @@ function isWritableRole(role) {
|
|
|
95
107
|
function mergeRoles(roleA, roleB) {
|
|
96
108
|
return roleA | roleB;
|
|
97
109
|
}
|
|
98
|
-
|
|
99
|
-
// src/durable-nonce.ts
|
|
100
110
|
var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
|
|
101
111
|
var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
102
112
|
function assertIsDurableNonceTransaction(transaction) {
|
|
103
113
|
if (!isDurableNonceTransaction(transaction)) {
|
|
104
|
-
throw new
|
|
114
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME);
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
117
|
function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
|
|
@@ -187,21 +197,181 @@ function setTransactionFeePayer(feePayer, transaction) {
|
|
|
187
197
|
|
|
188
198
|
// src/instructions.ts
|
|
189
199
|
function appendTransactionInstruction(instruction, transaction) {
|
|
200
|
+
return appendTransactionInstructions([instruction], transaction);
|
|
201
|
+
}
|
|
202
|
+
function appendTransactionInstructions(instructions, transaction) {
|
|
190
203
|
const out = {
|
|
191
204
|
...getUnsignedTransaction(transaction),
|
|
192
|
-
instructions: [...transaction.instructions,
|
|
205
|
+
instructions: [...transaction.instructions, ...instructions]
|
|
193
206
|
};
|
|
194
207
|
Object.freeze(out);
|
|
195
208
|
return out;
|
|
196
209
|
}
|
|
197
210
|
function prependTransactionInstruction(instruction, transaction) {
|
|
211
|
+
return prependTransactionInstructions([instruction], transaction);
|
|
212
|
+
}
|
|
213
|
+
function prependTransactionInstructions(instructions, transaction) {
|
|
198
214
|
const out = {
|
|
199
215
|
...getUnsignedTransaction(transaction),
|
|
200
|
-
instructions: [
|
|
216
|
+
instructions: [...instructions, ...transaction.instructions]
|
|
201
217
|
};
|
|
202
218
|
Object.freeze(out);
|
|
203
219
|
return out;
|
|
204
220
|
}
|
|
221
|
+
|
|
222
|
+
// src/decompile-transaction.ts
|
|
223
|
+
function getAccountMetas(message) {
|
|
224
|
+
const { header } = message;
|
|
225
|
+
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
226
|
+
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
227
|
+
const accountMetas = [];
|
|
228
|
+
let accountIndex = 0;
|
|
229
|
+
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
230
|
+
accountMetas.push({
|
|
231
|
+
address: message.staticAccounts[accountIndex],
|
|
232
|
+
role: AccountRole.WRITABLE_SIGNER
|
|
233
|
+
});
|
|
234
|
+
accountIndex++;
|
|
235
|
+
}
|
|
236
|
+
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
237
|
+
accountMetas.push({
|
|
238
|
+
address: message.staticAccounts[accountIndex],
|
|
239
|
+
role: AccountRole.READONLY_SIGNER
|
|
240
|
+
});
|
|
241
|
+
accountIndex++;
|
|
242
|
+
}
|
|
243
|
+
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
244
|
+
accountMetas.push({
|
|
245
|
+
address: message.staticAccounts[accountIndex],
|
|
246
|
+
role: AccountRole.WRITABLE
|
|
247
|
+
});
|
|
248
|
+
accountIndex++;
|
|
249
|
+
}
|
|
250
|
+
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
251
|
+
accountMetas.push({
|
|
252
|
+
address: message.staticAccounts[accountIndex],
|
|
253
|
+
role: AccountRole.READONLY
|
|
254
|
+
});
|
|
255
|
+
accountIndex++;
|
|
256
|
+
}
|
|
257
|
+
return accountMetas;
|
|
258
|
+
}
|
|
259
|
+
function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress) {
|
|
260
|
+
const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
|
|
261
|
+
const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
|
|
262
|
+
if (missing.length > 0) {
|
|
263
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {
|
|
264
|
+
lookupTableAddresses: missing
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const readOnlyMetas = [];
|
|
268
|
+
const writableMetas = [];
|
|
269
|
+
for (const lookup of compiledAddressTableLookups) {
|
|
270
|
+
const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
|
|
271
|
+
const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
|
|
272
|
+
if (highestIndex >= addresses.length) {
|
|
273
|
+
throw new errors.SolanaError(
|
|
274
|
+
errors.SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,
|
|
275
|
+
{
|
|
276
|
+
highestKnownIndex: addresses.length - 1,
|
|
277
|
+
highestRequestedIndex: highestIndex,
|
|
278
|
+
lookupTableAddress: lookup.lookupTableAddress
|
|
279
|
+
}
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
const readOnlyForLookup = lookup.readableIndices.map((r) => ({
|
|
283
|
+
address: addresses[r],
|
|
284
|
+
addressIndex: r,
|
|
285
|
+
lookupTableAddress: lookup.lookupTableAddress,
|
|
286
|
+
role: AccountRole.READONLY
|
|
287
|
+
}));
|
|
288
|
+
readOnlyMetas.push(...readOnlyForLookup);
|
|
289
|
+
const writableForLookup = lookup.writableIndices.map((w) => ({
|
|
290
|
+
address: addresses[w],
|
|
291
|
+
addressIndex: w,
|
|
292
|
+
lookupTableAddress: lookup.lookupTableAddress,
|
|
293
|
+
role: AccountRole.WRITABLE
|
|
294
|
+
}));
|
|
295
|
+
writableMetas.push(...writableForLookup);
|
|
296
|
+
}
|
|
297
|
+
return [...writableMetas, ...readOnlyMetas];
|
|
298
|
+
}
|
|
299
|
+
function convertInstruction(instruction, accountMetas) {
|
|
300
|
+
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
301
|
+
if (!programAddress) {
|
|
302
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {
|
|
303
|
+
index: instruction.programAddressIndex
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
307
|
+
const { data } = instruction;
|
|
308
|
+
return {
|
|
309
|
+
programAddress,
|
|
310
|
+
...accounts && accounts.length ? { accounts } : {},
|
|
311
|
+
...data && data.length ? { data } : {}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
315
|
+
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
316
|
+
return {
|
|
317
|
+
blockhash: messageLifetimeToken,
|
|
318
|
+
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
319
|
+
// U64 MAX
|
|
320
|
+
};
|
|
321
|
+
} else {
|
|
322
|
+
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
323
|
+
addresses.assertIsAddress(nonceAccountAddress);
|
|
324
|
+
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
325
|
+
addresses.assertIsAddress(nonceAuthorityAddress);
|
|
326
|
+
return {
|
|
327
|
+
nonce: messageLifetimeToken,
|
|
328
|
+
nonceAccountAddress,
|
|
329
|
+
nonceAuthorityAddress
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function convertSignatures(compiledTransaction) {
|
|
334
|
+
const {
|
|
335
|
+
compiledMessage: { staticAccounts },
|
|
336
|
+
signatures
|
|
337
|
+
} = compiledTransaction;
|
|
338
|
+
return signatures.reduce((acc, sig, index) => {
|
|
339
|
+
const allZeros = sig.every((byte) => byte === 0);
|
|
340
|
+
if (allZeros)
|
|
341
|
+
return acc;
|
|
342
|
+
const address = staticAccounts[index];
|
|
343
|
+
return { ...acc, [address]: sig };
|
|
344
|
+
}, {});
|
|
345
|
+
}
|
|
346
|
+
function decompileTransaction(compiledTransaction, config) {
|
|
347
|
+
const { compiledMessage } = compiledTransaction;
|
|
348
|
+
const feePayer = compiledMessage.staticAccounts[0];
|
|
349
|
+
if (!feePayer) {
|
|
350
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING);
|
|
351
|
+
}
|
|
352
|
+
const accountMetas = getAccountMetas(compiledMessage);
|
|
353
|
+
const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
|
|
354
|
+
const transactionMetas = [...accountMetas, ...accountLookupMetas];
|
|
355
|
+
const instructions = compiledMessage.instructions.map(
|
|
356
|
+
(compiledInstruction) => convertInstruction(compiledInstruction, transactionMetas)
|
|
357
|
+
);
|
|
358
|
+
const firstInstruction = instructions[0];
|
|
359
|
+
const lifetimeConstraint = getLifetimeConstraint(
|
|
360
|
+
compiledMessage.lifetimeToken,
|
|
361
|
+
firstInstruction,
|
|
362
|
+
config?.lastValidBlockHeight
|
|
363
|
+
);
|
|
364
|
+
const signatures = convertSignatures(compiledTransaction);
|
|
365
|
+
return functional.pipe(
|
|
366
|
+
createTransaction({ version: compiledMessage.version }),
|
|
367
|
+
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
368
|
+
(tx) => instructions.reduce((acc, instruction) => {
|
|
369
|
+
return appendTransactionInstruction(instruction, acc);
|
|
370
|
+
}, tx),
|
|
371
|
+
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
372
|
+
(tx) => Object.keys(signatures).length > 0 ? { ...tx, signatures } : tx
|
|
373
|
+
);
|
|
374
|
+
}
|
|
205
375
|
function upsert(addressMap, address, update) {
|
|
206
376
|
addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
|
|
207
377
|
}
|
|
@@ -218,13 +388,13 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
218
388
|
if (isWritableRole(entry.role)) {
|
|
219
389
|
switch (entry[TYPE]) {
|
|
220
390
|
case 0 /* FEE_PAYER */:
|
|
221
|
-
throw new
|
|
222
|
-
|
|
223
|
-
);
|
|
391
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES, {
|
|
392
|
+
programAddress: instruction.programAddress
|
|
393
|
+
});
|
|
224
394
|
default:
|
|
225
|
-
throw new
|
|
226
|
-
|
|
227
|
-
);
|
|
395
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE, {
|
|
396
|
+
programAddress: instruction.programAddress
|
|
397
|
+
});
|
|
228
398
|
}
|
|
229
399
|
}
|
|
230
400
|
if (entry[TYPE] === 2 /* STATIC */) {
|
|
@@ -289,8 +459,11 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
289
459
|
addressesOfInvokedPrograms.has(account.address)
|
|
290
460
|
) {
|
|
291
461
|
if (isWritableRole(accountMeta.role)) {
|
|
292
|
-
throw new
|
|
293
|
-
|
|
462
|
+
throw new errors.SolanaError(
|
|
463
|
+
errors.SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,
|
|
464
|
+
{
|
|
465
|
+
programAddress: account.address
|
|
466
|
+
}
|
|
294
467
|
);
|
|
295
468
|
}
|
|
296
469
|
if (entry.role !== nextRole) {
|
|
@@ -467,59 +640,31 @@ function compileMessage(transaction) {
|
|
|
467
640
|
version: transaction.version
|
|
468
641
|
};
|
|
469
642
|
}
|
|
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
643
|
var memoizedAddressTableLookupEncoder;
|
|
475
644
|
function getAddressTableLookupEncoder() {
|
|
476
645
|
if (!memoizedAddressTableLookupEncoder) {
|
|
477
|
-
memoizedAddressTableLookupEncoder = codecsDataStructures.getStructEncoder(
|
|
646
|
+
memoizedAddressTableLookupEncoder = codecsDataStructures.getStructEncoder([
|
|
647
|
+
["lookupTableAddress", addresses.getAddressEncoder()],
|
|
478
648
|
[
|
|
479
|
-
|
|
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
|
-
]
|
|
649
|
+
"writableIndices",
|
|
650
|
+
codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })
|
|
494
651
|
],
|
|
495
|
-
|
|
496
|
-
|
|
652
|
+
[
|
|
653
|
+
"readableIndices",
|
|
654
|
+
codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })
|
|
655
|
+
]
|
|
656
|
+
]);
|
|
497
657
|
}
|
|
498
658
|
return memoizedAddressTableLookupEncoder;
|
|
499
659
|
}
|
|
500
660
|
var memoizedAddressTableLookupDecoder;
|
|
501
661
|
function getAddressTableLookupDecoder() {
|
|
502
662
|
if (!memoizedAddressTableLookupDecoder) {
|
|
503
|
-
memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder(
|
|
504
|
-
[
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
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
|
-
]
|
|
520
|
-
],
|
|
521
|
-
{ description: addressTableLookupDescription }
|
|
522
|
-
);
|
|
663
|
+
memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder([
|
|
664
|
+
["lookupTableAddress", addresses.getAddressDecoder()],
|
|
665
|
+
["writableIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })],
|
|
666
|
+
["readableIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })]
|
|
667
|
+
]);
|
|
523
668
|
}
|
|
524
669
|
return memoizedAddressTableLookupDecoder;
|
|
525
670
|
}
|
|
@@ -529,72 +674,34 @@ function getMemoizedU8Encoder() {
|
|
|
529
674
|
memoizedU8Encoder = codecsNumbers.getU8Encoder();
|
|
530
675
|
return memoizedU8Encoder;
|
|
531
676
|
}
|
|
532
|
-
function getMemoizedU8EncoderDescription(description) {
|
|
533
|
-
const encoder = getMemoizedU8Encoder();
|
|
534
|
-
return {
|
|
535
|
-
...encoder,
|
|
536
|
-
description: description ?? encoder.description
|
|
537
|
-
};
|
|
538
|
-
}
|
|
539
677
|
var memoizedU8Decoder;
|
|
540
678
|
function getMemoizedU8Decoder() {
|
|
541
679
|
if (!memoizedU8Decoder)
|
|
542
680
|
memoizedU8Decoder = codecsNumbers.getU8Decoder();
|
|
543
681
|
return memoizedU8Decoder;
|
|
544
682
|
}
|
|
545
|
-
function getMemoizedU8DecoderDescription(description) {
|
|
546
|
-
const decoder = getMemoizedU8Decoder();
|
|
547
|
-
return {
|
|
548
|
-
...decoder,
|
|
549
|
-
description: description ?? decoder.description
|
|
550
|
-
};
|
|
551
|
-
}
|
|
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
683
|
function getMessageHeaderEncoder() {
|
|
557
|
-
return codecsDataStructures.getStructEncoder(
|
|
558
|
-
[
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
],
|
|
563
|
-
{
|
|
564
|
-
description: messageHeaderDescription
|
|
565
|
-
}
|
|
566
|
-
);
|
|
684
|
+
return codecsDataStructures.getStructEncoder([
|
|
685
|
+
["numSignerAccounts", getMemoizedU8Encoder()],
|
|
686
|
+
["numReadonlySignerAccounts", getMemoizedU8Encoder()],
|
|
687
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8Encoder()]
|
|
688
|
+
]);
|
|
567
689
|
}
|
|
568
690
|
function getMessageHeaderDecoder() {
|
|
569
|
-
return codecsDataStructures.getStructDecoder(
|
|
570
|
-
[
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
],
|
|
575
|
-
{
|
|
576
|
-
description: messageHeaderDescription
|
|
577
|
-
}
|
|
578
|
-
);
|
|
691
|
+
return codecsDataStructures.getStructDecoder([
|
|
692
|
+
["numSignerAccounts", getMemoizedU8Decoder()],
|
|
693
|
+
["numReadonlySignerAccounts", getMemoizedU8Decoder()],
|
|
694
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8Decoder()]
|
|
695
|
+
]);
|
|
579
696
|
}
|
|
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
697
|
var memoizedGetInstructionEncoder;
|
|
585
698
|
function getInstructionEncoder() {
|
|
586
699
|
if (!memoizedGetInstructionEncoder) {
|
|
587
700
|
memoizedGetInstructionEncoder = codecsCore.mapEncoder(
|
|
588
701
|
codecsDataStructures.getStructEncoder([
|
|
589
|
-
["programAddressIndex", codecsNumbers.getU8Encoder(
|
|
590
|
-
[
|
|
591
|
-
|
|
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() })]
|
|
702
|
+
["programAddressIndex", codecsNumbers.getU8Encoder()],
|
|
703
|
+
["accountIndices", codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })],
|
|
704
|
+
["data", codecsDataStructures.getBytesEncoder({ size: codecsNumbers.getShortU16Encoder() })]
|
|
598
705
|
]),
|
|
599
706
|
// Convert an instruction to have all fields defined
|
|
600
707
|
(instruction) => {
|
|
@@ -616,15 +723,9 @@ function getInstructionDecoder() {
|
|
|
616
723
|
if (!memoizedGetInstructionDecoder) {
|
|
617
724
|
memoizedGetInstructionDecoder = codecsCore.mapDecoder(
|
|
618
725
|
codecsDataStructures.getStructDecoder([
|
|
619
|
-
["programAddressIndex", codecsNumbers.getU8Decoder(
|
|
620
|
-
[
|
|
621
|
-
|
|
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() })]
|
|
726
|
+
["programAddressIndex", codecsNumbers.getU8Decoder()],
|
|
727
|
+
["accountIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })],
|
|
728
|
+
["data", codecsDataStructures.getBytesDecoder({ size: codecsNumbers.getShortU16Decoder() })]
|
|
628
729
|
]),
|
|
629
730
|
// Convert an instruction to exclude optional fields if they are empty
|
|
630
731
|
(instruction) => {
|
|
@@ -643,47 +744,40 @@ function getInstructionDecoder() {
|
|
|
643
744
|
return memoizedGetInstructionDecoder;
|
|
644
745
|
}
|
|
645
746
|
var VERSION_FLAG_MASK = 128;
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
}
|
|
664
|
-
if (value < 0 || value > 127) {
|
|
665
|
-
throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
|
|
666
|
-
}
|
|
667
|
-
return new Uint8Array([value | VERSION_FLAG_MASK]);
|
|
747
|
+
function getTransactionVersionEncoder() {
|
|
748
|
+
return codecsCore.createEncoder({
|
|
749
|
+
getSizeFromValue: (value) => value === "legacy" ? 0 : 1,
|
|
750
|
+
maxSize: 1,
|
|
751
|
+
write: (value, bytes, offset) => {
|
|
752
|
+
if (value === "legacy") {
|
|
753
|
+
return offset;
|
|
754
|
+
}
|
|
755
|
+
if (value < 0 || value > 127) {
|
|
756
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE, {
|
|
757
|
+
actualVersion: value
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
bytes.set([value | VERSION_FLAG_MASK], offset);
|
|
761
|
+
return offset + 1;
|
|
762
|
+
}
|
|
763
|
+
});
|
|
668
764
|
}
|
|
669
765
|
function getTransactionVersionDecoder() {
|
|
670
|
-
return {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
766
|
+
return codecsCore.createDecoder({
|
|
767
|
+
maxSize: 1,
|
|
768
|
+
read: (bytes, offset) => {
|
|
769
|
+
const firstByte = bytes[offset];
|
|
770
|
+
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
771
|
+
return ["legacy", offset];
|
|
772
|
+
} else {
|
|
773
|
+
const version = firstByte ^ VERSION_FLAG_MASK;
|
|
774
|
+
return [version, offset + 1];
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
});
|
|
680
778
|
}
|
|
681
779
|
|
|
682
780
|
// src/serializers/message.ts
|
|
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
781
|
function getCompiledMessageLegacyEncoder() {
|
|
688
782
|
return codecsDataStructures.getStructEncoder(getPreludeStructEncoderTuple());
|
|
689
783
|
}
|
|
@@ -708,91 +802,48 @@ function getPreludeStructEncoderTuple() {
|
|
|
708
802
|
return [
|
|
709
803
|
["version", getTransactionVersionEncoder()],
|
|
710
804
|
["header", getMessageHeaderEncoder()],
|
|
711
|
-
[
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
description: staticAccountsDescription,
|
|
715
|
-
size: codecsNumbers.getShortU16Encoder()
|
|
716
|
-
})
|
|
717
|
-
],
|
|
718
|
-
[
|
|
719
|
-
"lifetimeToken",
|
|
720
|
-
codecsStrings.getStringEncoder({
|
|
721
|
-
description: lifetimeTokenDescription,
|
|
722
|
-
encoding: codecsStrings.getBase58Encoder(),
|
|
723
|
-
size: 32
|
|
724
|
-
})
|
|
725
|
-
],
|
|
726
|
-
[
|
|
727
|
-
"instructions",
|
|
728
|
-
codecsDataStructures.getArrayEncoder(getInstructionEncoder(), {
|
|
729
|
-
description: instructionsDescription,
|
|
730
|
-
size: codecsNumbers.getShortU16Encoder()
|
|
731
|
-
})
|
|
732
|
-
]
|
|
805
|
+
["staticAccounts", codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), { size: codecsNumbers.getShortU16Encoder() })],
|
|
806
|
+
["lifetimeToken", codecsStrings.getStringEncoder({ encoding: codecsStrings.getBase58Encoder(), size: 32 })],
|
|
807
|
+
["instructions", codecsDataStructures.getArrayEncoder(getInstructionEncoder(), { size: codecsNumbers.getShortU16Encoder() })]
|
|
733
808
|
];
|
|
734
809
|
}
|
|
735
810
|
function getPreludeStructDecoderTuple() {
|
|
736
811
|
return [
|
|
737
812
|
["version", getTransactionVersionDecoder()],
|
|
738
813
|
["header", getMessageHeaderDecoder()],
|
|
739
|
-
[
|
|
740
|
-
|
|
741
|
-
|
|
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
|
-
],
|
|
814
|
+
["staticAccounts", codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), { size: codecsNumbers.getShortU16Decoder() })],
|
|
815
|
+
["lifetimeToken", codecsStrings.getStringDecoder({ encoding: codecsStrings.getBase58Decoder(), size: 32 })],
|
|
816
|
+
["instructions", codecsDataStructures.getArrayDecoder(getInstructionDecoder(), { size: codecsNumbers.getShortU16Decoder() })],
|
|
761
817
|
["addressTableLookups", getAddressTableLookupArrayDecoder()]
|
|
762
818
|
];
|
|
763
819
|
}
|
|
764
820
|
function getAddressTableLookupArrayEncoder() {
|
|
765
|
-
return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), {
|
|
766
|
-
description: addressTableLookupsDescription,
|
|
767
|
-
size: codecsNumbers.getShortU16Encoder()
|
|
768
|
-
});
|
|
821
|
+
return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), { size: codecsNumbers.getShortU16Encoder() });
|
|
769
822
|
}
|
|
770
823
|
function getAddressTableLookupArrayDecoder() {
|
|
771
|
-
return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
|
|
772
|
-
description: addressTableLookupsDescription,
|
|
773
|
-
size: codecsNumbers.getShortU16Decoder()
|
|
774
|
-
});
|
|
824
|
+
return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), { size: codecsNumbers.getShortU16Decoder() });
|
|
775
825
|
}
|
|
776
|
-
var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
|
|
777
826
|
function getCompiledMessageEncoder() {
|
|
778
|
-
return {
|
|
779
|
-
|
|
780
|
-
encode: (compiledMessage) => {
|
|
827
|
+
return codecsCore.createEncoder({
|
|
828
|
+
getSizeFromValue: (compiledMessage) => {
|
|
781
829
|
if (compiledMessage.version === "legacy") {
|
|
782
|
-
return getCompiledMessageLegacyEncoder().
|
|
830
|
+
return getCompiledMessageLegacyEncoder().getSizeFromValue(compiledMessage);
|
|
783
831
|
} else {
|
|
784
|
-
return getCompiledMessageVersionedEncoder().
|
|
832
|
+
return getCompiledMessageVersionedEncoder().getSizeFromValue(compiledMessage);
|
|
785
833
|
}
|
|
786
834
|
},
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
835
|
+
write: (compiledMessage, bytes, offset) => {
|
|
836
|
+
if (compiledMessage.version === "legacy") {
|
|
837
|
+
return getCompiledMessageLegacyEncoder().write(compiledMessage, bytes, offset);
|
|
838
|
+
} else {
|
|
839
|
+
return getCompiledMessageVersionedEncoder().write(compiledMessage, bytes, offset);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
});
|
|
790
843
|
}
|
|
791
844
|
function getCompiledMessageDecoder() {
|
|
792
845
|
return codecsCore.mapDecoder(
|
|
793
|
-
codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple(),
|
|
794
|
-
description: messageDescription
|
|
795
|
-
}),
|
|
846
|
+
codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple()),
|
|
796
847
|
({ addressTableLookups, ...restOfMessage }) => {
|
|
797
848
|
if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
|
|
798
849
|
return restOfMessage;
|
|
@@ -822,168 +873,36 @@ function getCompiledTransaction(transaction) {
|
|
|
822
873
|
signatures
|
|
823
874
|
};
|
|
824
875
|
}
|
|
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
|
-
}
|
|
935
876
|
|
|
936
877
|
// src/serializers/transaction.ts
|
|
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
878
|
function getCompiledTransactionEncoder() {
|
|
940
|
-
return codecsDataStructures.getStructEncoder(
|
|
941
|
-
[
|
|
942
|
-
|
|
943
|
-
|
|
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);
|
|
879
|
+
return codecsDataStructures.getStructEncoder([
|
|
880
|
+
["signatures", codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), { size: codecsNumbers.getShortU16Encoder() })],
|
|
881
|
+
["compiledMessage", getCompiledMessageEncoder()]
|
|
882
|
+
]);
|
|
958
883
|
}
|
|
959
884
|
function getCompiledTransactionDecoder() {
|
|
960
|
-
return codecsDataStructures.getStructDecoder(
|
|
885
|
+
return codecsDataStructures.getStructDecoder([
|
|
961
886
|
[
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
size: codecsNumbers.getShortU16Decoder()
|
|
967
|
-
})
|
|
968
|
-
],
|
|
969
|
-
["compiledMessage", getCompiledMessageDecoder()]
|
|
887
|
+
"signatures",
|
|
888
|
+
codecsDataStructures.getArrayDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), {
|
|
889
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
890
|
+
})
|
|
970
891
|
],
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
}
|
|
974
|
-
);
|
|
892
|
+
["compiledMessage", getCompiledMessageDecoder()]
|
|
893
|
+
]);
|
|
975
894
|
}
|
|
976
895
|
function getTransactionEncoder() {
|
|
977
896
|
return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
|
|
978
897
|
}
|
|
979
|
-
function getTransactionDecoder(
|
|
898
|
+
function getTransactionDecoder(config) {
|
|
980
899
|
return codecsCore.mapDecoder(
|
|
981
900
|
getCompiledTransactionDecoder(),
|
|
982
|
-
(compiledTransaction) => decompileTransaction(compiledTransaction,
|
|
901
|
+
(compiledTransaction) => decompileTransaction(compiledTransaction, config)
|
|
983
902
|
);
|
|
984
903
|
}
|
|
985
|
-
function getTransactionCodec(
|
|
986
|
-
return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(
|
|
904
|
+
function getTransactionCodec(config) {
|
|
905
|
+
return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(config));
|
|
987
906
|
}
|
|
988
907
|
var base58Decoder;
|
|
989
908
|
function getSignatureFromTransaction(transaction) {
|
|
@@ -991,11 +910,9 @@ function getSignatureFromTransaction(transaction) {
|
|
|
991
910
|
base58Decoder = codecsStrings.getBase58Decoder();
|
|
992
911
|
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
993
912
|
if (!signatureBytes) {
|
|
994
|
-
throw new
|
|
995
|
-
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
996
|
-
);
|
|
913
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING);
|
|
997
914
|
}
|
|
998
|
-
const transactionSignature = base58Decoder.decode(signatureBytes)
|
|
915
|
+
const transactionSignature = base58Decoder.decode(signatureBytes);
|
|
999
916
|
return transactionSignature;
|
|
1000
917
|
}
|
|
1001
918
|
async function partiallySignTransaction(keyPairs, transaction) {
|
|
@@ -1026,34 +943,45 @@ async function signTransaction(keyPairs, transaction) {
|
|
|
1026
943
|
function assertTransactionIsFullySigned(transaction) {
|
|
1027
944
|
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
|
|
1028
945
|
const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
|
|
946
|
+
const missingSigs = [];
|
|
1029
947
|
requiredSigners.forEach((address) => {
|
|
1030
948
|
if (!transaction.signatures[address]) {
|
|
1031
|
-
|
|
949
|
+
missingSigs.push(address);
|
|
1032
950
|
}
|
|
1033
951
|
});
|
|
952
|
+
if (missingSigs.length > 0) {
|
|
953
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {
|
|
954
|
+
addresses: missingSigs
|
|
955
|
+
});
|
|
956
|
+
}
|
|
1034
957
|
}
|
|
1035
958
|
function getBase64EncodedWireTransaction(transaction) {
|
|
1036
959
|
const wireTransactionBytes = getTransactionEncoder().encode(transaction);
|
|
1037
|
-
return codecsStrings.getBase64Decoder().decode(wireTransactionBytes)
|
|
960
|
+
return codecsStrings.getBase64Decoder().decode(wireTransactionBytes);
|
|
1038
961
|
}
|
|
1039
962
|
|
|
1040
963
|
exports.appendTransactionInstruction = appendTransactionInstruction;
|
|
1041
|
-
exports.
|
|
964
|
+
exports.appendTransactionInstructions = appendTransactionInstructions;
|
|
1042
965
|
exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
|
|
966
|
+
exports.assertIsTransactionWithBlockhashLifetime = assertIsTransactionWithBlockhashLifetime;
|
|
1043
967
|
exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
|
|
1044
968
|
exports.compileMessage = compileMessage;
|
|
1045
969
|
exports.createTransaction = createTransaction;
|
|
970
|
+
exports.decompileTransaction = decompileTransaction;
|
|
1046
971
|
exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
|
|
1047
972
|
exports.getCompiledMessageCodec = getCompiledMessageCodec;
|
|
1048
973
|
exports.getCompiledMessageDecoder = getCompiledMessageDecoder;
|
|
1049
974
|
exports.getCompiledMessageEncoder = getCompiledMessageEncoder;
|
|
975
|
+
exports.getCompiledTransactionDecoder = getCompiledTransactionDecoder;
|
|
1050
976
|
exports.getSignatureFromTransaction = getSignatureFromTransaction;
|
|
1051
977
|
exports.getTransactionCodec = getTransactionCodec;
|
|
1052
978
|
exports.getTransactionDecoder = getTransactionDecoder;
|
|
1053
979
|
exports.getTransactionEncoder = getTransactionEncoder;
|
|
980
|
+
exports.getUnsignedTransaction = getUnsignedTransaction;
|
|
1054
981
|
exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
|
|
1055
982
|
exports.partiallySignTransaction = partiallySignTransaction;
|
|
1056
983
|
exports.prependTransactionInstruction = prependTransactionInstruction;
|
|
984
|
+
exports.prependTransactionInstructions = prependTransactionInstructions;
|
|
1057
985
|
exports.setTransactionFeePayer = setTransactionFeePayer;
|
|
1058
986
|
exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
|
|
1059
987
|
exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
|