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