@solana/transactions 2.0.0-experimental.a48ebd2 → 2.0.0-experimental.a53387e
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 +321 -398
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +321 -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 +321 -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.js
CHANGED
|
@@ -1,13 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { getStructDecoder, getStructEncoder, getArrayEncoder, getArrayDecoder, getBytesEncoder, getBytesDecoder } from '@solana/codecs-data-structures';
|
|
5
|
-
import { getShortU16Encoder, getShortU16Decoder, getU8Encoder, getU8Decoder } from '@solana/codecs-numbers';
|
|
1
|
+
import { SolanaError, SOLANA_ERROR__TRANSACTION_EXPECTED_BLOCKHASH_LIFETIME, SOLANA_ERROR__TRANSACTION_EXPECTED_NONCE_LIFETIME, SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_FEE_PAYER_MISSING, SOLANA_ERROR__TRANSACTION_SIGNATURE_NOT_COMPUTABLE, SOLANA_ERROR__TRANSACTION_MISSING_SIGNATURES, SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE, SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE, SOLANA_ERROR__BLOCKHASH_BYTE_LENGTH_OUT_OF_RANGE, SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE, SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_CANNOT_PAY_FEES, SOLANA_ERROR__TRANSACTION_VERSION_NUMBER_OUT_OF_RANGE } from '@solana/errors';
|
|
2
|
+
import { getBase58Decoder, getBase64Decoder, getStringEncoder, getBase58Encoder, getStringDecoder } from '@solana/codecs-strings';
|
|
3
|
+
import { getAddressFromPublicKey, assertIsAddress, getAddressComparator, getAddressEncoder, getAddressDecoder } from '@solana/addresses';
|
|
6
4
|
import { pipe } from '@solana/functional';
|
|
5
|
+
import { createEncoder, mapDecoder, combineCodec, mapEncoder, createDecoder } from '@solana/codecs-core';
|
|
6
|
+
import { getStructDecoder, getArrayDecoder, getBytesDecoder, getStructEncoder, getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';
|
|
7
|
+
import { getShortU16Decoder, getShortU16Encoder, getU8Encoder, getU8Decoder } from '@solana/codecs-numbers';
|
|
7
8
|
import { signBytes } from '@solana/keys';
|
|
8
9
|
|
|
9
|
-
//
|
|
10
|
-
var
|
|
10
|
+
// src/blockhash.ts
|
|
11
|
+
var base58Encoder;
|
|
12
|
+
function assertIsBlockhash(putativeBlockhash) {
|
|
13
|
+
if (!base58Encoder)
|
|
14
|
+
base58Encoder = getBase58Encoder();
|
|
15
|
+
if (
|
|
16
|
+
// Lowest value (32 bytes of zeroes)
|
|
17
|
+
putativeBlockhash.length < 32 || // Highest value (32 bytes of 255)
|
|
18
|
+
putativeBlockhash.length > 44
|
|
19
|
+
) {
|
|
20
|
+
throw new SolanaError(SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE, {
|
|
21
|
+
actualLength: putativeBlockhash.length
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const bytes = base58Encoder.encode(putativeBlockhash);
|
|
25
|
+
const numBytes = bytes.byteLength;
|
|
26
|
+
if (numBytes !== 32) {
|
|
27
|
+
throw new SolanaError(SOLANA_ERROR__BLOCKHASH_BYTE_LENGTH_OUT_OF_RANGE, {
|
|
28
|
+
actualLength: numBytes
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
11
32
|
|
|
12
33
|
// src/unsigned-transaction.ts
|
|
13
34
|
function getUnsignedTransaction(transaction) {
|
|
@@ -24,27 +45,20 @@ function getUnsignedTransaction(transaction) {
|
|
|
24
45
|
}
|
|
25
46
|
|
|
26
47
|
// src/blockhash.ts
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (!
|
|
30
|
-
|
|
48
|
+
function isTransactionWithBlockhashLifetime(transaction) {
|
|
49
|
+
const lifetimeConstraintShapeMatches = "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.blockhash === "string" && typeof transaction.lifetimeConstraint.lastValidBlockHeight === "bigint";
|
|
50
|
+
if (!lifetimeConstraintShapeMatches)
|
|
51
|
+
return false;
|
|
31
52
|
try {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (numBytes !== 32) {
|
|
42
|
-
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
43
|
-
}
|
|
44
|
-
} catch (e) {
|
|
45
|
-
throw new Error(`\`${putativeBlockhash}\` is not a blockhash`, {
|
|
46
|
-
cause: e
|
|
47
|
-
});
|
|
53
|
+
assertIsBlockhash(transaction.lifetimeConstraint.blockhash);
|
|
54
|
+
return true;
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function assertIsTransactionWithBlockhashLifetime(transaction) {
|
|
60
|
+
if (!isTransactionWithBlockhashLifetime(transaction)) {
|
|
61
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_EXPECTED_BLOCKHASH_LIFETIME);
|
|
48
62
|
}
|
|
49
63
|
}
|
|
50
64
|
function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
|
|
@@ -70,8 +84,6 @@ function createTransaction({
|
|
|
70
84
|
Object.freeze(out);
|
|
71
85
|
return out;
|
|
72
86
|
}
|
|
73
|
-
|
|
74
|
-
// ../instructions/dist/index.browser.js
|
|
75
87
|
var AccountRole = /* @__PURE__ */ ((AccountRole2) => {
|
|
76
88
|
AccountRole2[AccountRole2["WRITABLE_SIGNER"] = /* 3 */
|
|
77
89
|
3] = "WRITABLE_SIGNER";
|
|
@@ -93,13 +105,11 @@ function isWritableRole(role) {
|
|
|
93
105
|
function mergeRoles(roleA, roleB) {
|
|
94
106
|
return roleA | roleB;
|
|
95
107
|
}
|
|
96
|
-
|
|
97
|
-
// src/durable-nonce.ts
|
|
98
108
|
var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
|
|
99
109
|
var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
100
110
|
function assertIsDurableNonceTransaction(transaction) {
|
|
101
111
|
if (!isDurableNonceTransaction(transaction)) {
|
|
102
|
-
throw new
|
|
112
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_EXPECTED_NONCE_LIFETIME);
|
|
103
113
|
}
|
|
104
114
|
}
|
|
105
115
|
function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
|
|
@@ -185,21 +195,181 @@ function setTransactionFeePayer(feePayer, transaction) {
|
|
|
185
195
|
|
|
186
196
|
// src/instructions.ts
|
|
187
197
|
function appendTransactionInstruction(instruction, transaction) {
|
|
198
|
+
return appendTransactionInstructions([instruction], transaction);
|
|
199
|
+
}
|
|
200
|
+
function appendTransactionInstructions(instructions, transaction) {
|
|
188
201
|
const out = {
|
|
189
202
|
...getUnsignedTransaction(transaction),
|
|
190
|
-
instructions: [...transaction.instructions,
|
|
203
|
+
instructions: [...transaction.instructions, ...instructions]
|
|
191
204
|
};
|
|
192
205
|
Object.freeze(out);
|
|
193
206
|
return out;
|
|
194
207
|
}
|
|
195
208
|
function prependTransactionInstruction(instruction, transaction) {
|
|
209
|
+
return prependTransactionInstructions([instruction], transaction);
|
|
210
|
+
}
|
|
211
|
+
function prependTransactionInstructions(instructions, transaction) {
|
|
196
212
|
const out = {
|
|
197
213
|
...getUnsignedTransaction(transaction),
|
|
198
|
-
instructions: [
|
|
214
|
+
instructions: [...instructions, ...transaction.instructions]
|
|
199
215
|
};
|
|
200
216
|
Object.freeze(out);
|
|
201
217
|
return out;
|
|
202
218
|
}
|
|
219
|
+
|
|
220
|
+
// src/decompile-transaction.ts
|
|
221
|
+
function getAccountMetas(message) {
|
|
222
|
+
const { header } = message;
|
|
223
|
+
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
224
|
+
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
225
|
+
const accountMetas = [];
|
|
226
|
+
let accountIndex = 0;
|
|
227
|
+
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
228
|
+
accountMetas.push({
|
|
229
|
+
address: message.staticAccounts[accountIndex],
|
|
230
|
+
role: AccountRole.WRITABLE_SIGNER
|
|
231
|
+
});
|
|
232
|
+
accountIndex++;
|
|
233
|
+
}
|
|
234
|
+
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
235
|
+
accountMetas.push({
|
|
236
|
+
address: message.staticAccounts[accountIndex],
|
|
237
|
+
role: AccountRole.READONLY_SIGNER
|
|
238
|
+
});
|
|
239
|
+
accountIndex++;
|
|
240
|
+
}
|
|
241
|
+
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
242
|
+
accountMetas.push({
|
|
243
|
+
address: message.staticAccounts[accountIndex],
|
|
244
|
+
role: AccountRole.WRITABLE
|
|
245
|
+
});
|
|
246
|
+
accountIndex++;
|
|
247
|
+
}
|
|
248
|
+
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
249
|
+
accountMetas.push({
|
|
250
|
+
address: message.staticAccounts[accountIndex],
|
|
251
|
+
role: AccountRole.READONLY
|
|
252
|
+
});
|
|
253
|
+
accountIndex++;
|
|
254
|
+
}
|
|
255
|
+
return accountMetas;
|
|
256
|
+
}
|
|
257
|
+
function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress) {
|
|
258
|
+
const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
|
|
259
|
+
const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
|
|
260
|
+
if (missing.length > 0) {
|
|
261
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {
|
|
262
|
+
lookupTableAddresses: missing
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
const readOnlyMetas = [];
|
|
266
|
+
const writableMetas = [];
|
|
267
|
+
for (const lookup of compiledAddressTableLookups) {
|
|
268
|
+
const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
|
|
269
|
+
const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
|
|
270
|
+
if (highestIndex >= addresses.length) {
|
|
271
|
+
throw new SolanaError(
|
|
272
|
+
SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,
|
|
273
|
+
{
|
|
274
|
+
highestKnownIndex: addresses.length - 1,
|
|
275
|
+
highestRequestedIndex: highestIndex,
|
|
276
|
+
lookupTableAddress: lookup.lookupTableAddress
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
const readOnlyForLookup = lookup.readableIndices.map((r) => ({
|
|
281
|
+
address: addresses[r],
|
|
282
|
+
addressIndex: r,
|
|
283
|
+
lookupTableAddress: lookup.lookupTableAddress,
|
|
284
|
+
role: AccountRole.READONLY
|
|
285
|
+
}));
|
|
286
|
+
readOnlyMetas.push(...readOnlyForLookup);
|
|
287
|
+
const writableForLookup = lookup.writableIndices.map((w) => ({
|
|
288
|
+
address: addresses[w],
|
|
289
|
+
addressIndex: w,
|
|
290
|
+
lookupTableAddress: lookup.lookupTableAddress,
|
|
291
|
+
role: AccountRole.WRITABLE
|
|
292
|
+
}));
|
|
293
|
+
writableMetas.push(...writableForLookup);
|
|
294
|
+
}
|
|
295
|
+
return [...writableMetas, ...readOnlyMetas];
|
|
296
|
+
}
|
|
297
|
+
function convertInstruction(instruction, accountMetas) {
|
|
298
|
+
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
299
|
+
if (!programAddress) {
|
|
300
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {
|
|
301
|
+
index: instruction.programAddressIndex
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
305
|
+
const { data } = instruction;
|
|
306
|
+
return {
|
|
307
|
+
programAddress,
|
|
308
|
+
...accounts && accounts.length ? { accounts } : {},
|
|
309
|
+
...data && data.length ? { data } : {}
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
313
|
+
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
314
|
+
return {
|
|
315
|
+
blockhash: messageLifetimeToken,
|
|
316
|
+
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
317
|
+
// U64 MAX
|
|
318
|
+
};
|
|
319
|
+
} else {
|
|
320
|
+
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
321
|
+
assertIsAddress(nonceAccountAddress);
|
|
322
|
+
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
323
|
+
assertIsAddress(nonceAuthorityAddress);
|
|
324
|
+
return {
|
|
325
|
+
nonce: messageLifetimeToken,
|
|
326
|
+
nonceAccountAddress,
|
|
327
|
+
nonceAuthorityAddress
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function convertSignatures(compiledTransaction) {
|
|
332
|
+
const {
|
|
333
|
+
compiledMessage: { staticAccounts },
|
|
334
|
+
signatures
|
|
335
|
+
} = compiledTransaction;
|
|
336
|
+
return signatures.reduce((acc, sig, index) => {
|
|
337
|
+
const allZeros = sig.every((byte) => byte === 0);
|
|
338
|
+
if (allZeros)
|
|
339
|
+
return acc;
|
|
340
|
+
const address = staticAccounts[index];
|
|
341
|
+
return { ...acc, [address]: sig };
|
|
342
|
+
}, {});
|
|
343
|
+
}
|
|
344
|
+
function decompileTransaction(compiledTransaction, config) {
|
|
345
|
+
const { compiledMessage } = compiledTransaction;
|
|
346
|
+
const feePayer = compiledMessage.staticAccounts[0];
|
|
347
|
+
if (!feePayer) {
|
|
348
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_FEE_PAYER_MISSING);
|
|
349
|
+
}
|
|
350
|
+
const accountMetas = getAccountMetas(compiledMessage);
|
|
351
|
+
const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
|
|
352
|
+
const transactionMetas = [...accountMetas, ...accountLookupMetas];
|
|
353
|
+
const instructions = compiledMessage.instructions.map(
|
|
354
|
+
(compiledInstruction) => convertInstruction(compiledInstruction, transactionMetas)
|
|
355
|
+
);
|
|
356
|
+
const firstInstruction = instructions[0];
|
|
357
|
+
const lifetimeConstraint = getLifetimeConstraint(
|
|
358
|
+
compiledMessage.lifetimeToken,
|
|
359
|
+
firstInstruction,
|
|
360
|
+
config?.lastValidBlockHeight
|
|
361
|
+
);
|
|
362
|
+
const signatures = convertSignatures(compiledTransaction);
|
|
363
|
+
return pipe(
|
|
364
|
+
createTransaction({ version: compiledMessage.version }),
|
|
365
|
+
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
366
|
+
(tx) => instructions.reduce((acc, instruction) => {
|
|
367
|
+
return appendTransactionInstruction(instruction, acc);
|
|
368
|
+
}, tx),
|
|
369
|
+
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
370
|
+
(tx) => Object.keys(signatures).length > 0 ? { ...tx, signatures } : tx
|
|
371
|
+
);
|
|
372
|
+
}
|
|
203
373
|
function upsert(addressMap, address, update) {
|
|
204
374
|
addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
|
|
205
375
|
}
|
|
@@ -216,13 +386,13 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
216
386
|
if (isWritableRole(entry.role)) {
|
|
217
387
|
switch (entry[TYPE]) {
|
|
218
388
|
case 0 /* FEE_PAYER */:
|
|
219
|
-
throw new
|
|
220
|
-
|
|
221
|
-
);
|
|
389
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_CANNOT_PAY_FEES, {
|
|
390
|
+
programAddress: instruction.programAddress
|
|
391
|
+
});
|
|
222
392
|
default:
|
|
223
|
-
throw new
|
|
224
|
-
|
|
225
|
-
);
|
|
393
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE, {
|
|
394
|
+
programAddress: instruction.programAddress
|
|
395
|
+
});
|
|
226
396
|
}
|
|
227
397
|
}
|
|
228
398
|
if (entry[TYPE] === 2 /* STATIC */) {
|
|
@@ -287,8 +457,11 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
287
457
|
addressesOfInvokedPrograms.has(account.address)
|
|
288
458
|
) {
|
|
289
459
|
if (isWritableRole(accountMeta.role)) {
|
|
290
|
-
throw new
|
|
291
|
-
|
|
460
|
+
throw new SolanaError(
|
|
461
|
+
SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,
|
|
462
|
+
{
|
|
463
|
+
programAddress: account.address
|
|
464
|
+
}
|
|
292
465
|
);
|
|
293
466
|
}
|
|
294
467
|
if (entry.role !== nextRole) {
|
|
@@ -465,59 +638,31 @@ function compileMessage(transaction) {
|
|
|
465
638
|
version: transaction.version
|
|
466
639
|
};
|
|
467
640
|
}
|
|
468
|
-
var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
|
|
469
|
-
var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
|
|
470
|
-
var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
|
|
471
|
-
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";
|
|
472
641
|
var memoizedAddressTableLookupEncoder;
|
|
473
642
|
function getAddressTableLookupEncoder() {
|
|
474
643
|
if (!memoizedAddressTableLookupEncoder) {
|
|
475
|
-
memoizedAddressTableLookupEncoder = getStructEncoder(
|
|
644
|
+
memoizedAddressTableLookupEncoder = getStructEncoder([
|
|
645
|
+
["lookupTableAddress", getAddressEncoder()],
|
|
476
646
|
[
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
"writableIndices",
|
|
480
|
-
getArrayEncoder(getU8Encoder(), {
|
|
481
|
-
description: writableIndicesDescription,
|
|
482
|
-
size: getShortU16Encoder()
|
|
483
|
-
})
|
|
484
|
-
],
|
|
485
|
-
[
|
|
486
|
-
"readableIndices",
|
|
487
|
-
getArrayEncoder(getU8Encoder(), {
|
|
488
|
-
description: readableIndicesDescription,
|
|
489
|
-
size: getShortU16Encoder()
|
|
490
|
-
})
|
|
491
|
-
]
|
|
647
|
+
"writableIndices",
|
|
648
|
+
getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })
|
|
492
649
|
],
|
|
493
|
-
|
|
494
|
-
|
|
650
|
+
[
|
|
651
|
+
"readableIndices",
|
|
652
|
+
getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })
|
|
653
|
+
]
|
|
654
|
+
]);
|
|
495
655
|
}
|
|
496
656
|
return memoizedAddressTableLookupEncoder;
|
|
497
657
|
}
|
|
498
658
|
var memoizedAddressTableLookupDecoder;
|
|
499
659
|
function getAddressTableLookupDecoder() {
|
|
500
660
|
if (!memoizedAddressTableLookupDecoder) {
|
|
501
|
-
memoizedAddressTableLookupDecoder = getStructDecoder(
|
|
502
|
-
[
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
getArrayDecoder(getU8Decoder(), {
|
|
507
|
-
description: writableIndicesDescription,
|
|
508
|
-
size: getShortU16Decoder()
|
|
509
|
-
})
|
|
510
|
-
],
|
|
511
|
-
[
|
|
512
|
-
"readableIndices",
|
|
513
|
-
getArrayDecoder(getU8Decoder(), {
|
|
514
|
-
description: readableIndicesDescription,
|
|
515
|
-
size: getShortU16Decoder()
|
|
516
|
-
})
|
|
517
|
-
]
|
|
518
|
-
],
|
|
519
|
-
{ description: addressTableLookupDescription }
|
|
520
|
-
);
|
|
661
|
+
memoizedAddressTableLookupDecoder = getStructDecoder([
|
|
662
|
+
["lookupTableAddress", getAddressDecoder()],
|
|
663
|
+
["writableIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })],
|
|
664
|
+
["readableIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })]
|
|
665
|
+
]);
|
|
521
666
|
}
|
|
522
667
|
return memoizedAddressTableLookupDecoder;
|
|
523
668
|
}
|
|
@@ -527,72 +672,34 @@ function getMemoizedU8Encoder() {
|
|
|
527
672
|
memoizedU8Encoder = getU8Encoder();
|
|
528
673
|
return memoizedU8Encoder;
|
|
529
674
|
}
|
|
530
|
-
function getMemoizedU8EncoderDescription(description) {
|
|
531
|
-
const encoder = getMemoizedU8Encoder();
|
|
532
|
-
return {
|
|
533
|
-
...encoder,
|
|
534
|
-
description: description ?? encoder.description
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
675
|
var memoizedU8Decoder;
|
|
538
676
|
function getMemoizedU8Decoder() {
|
|
539
677
|
if (!memoizedU8Decoder)
|
|
540
678
|
memoizedU8Decoder = getU8Decoder();
|
|
541
679
|
return memoizedU8Decoder;
|
|
542
680
|
}
|
|
543
|
-
function getMemoizedU8DecoderDescription(description) {
|
|
544
|
-
const decoder = getMemoizedU8Decoder();
|
|
545
|
-
return {
|
|
546
|
-
...decoder,
|
|
547
|
-
description: description ?? decoder.description
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
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;
|
|
551
|
-
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;
|
|
552
|
-
var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
|
|
553
|
-
var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
|
|
554
681
|
function getMessageHeaderEncoder() {
|
|
555
|
-
return getStructEncoder(
|
|
556
|
-
[
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
],
|
|
561
|
-
{
|
|
562
|
-
description: messageHeaderDescription
|
|
563
|
-
}
|
|
564
|
-
);
|
|
682
|
+
return getStructEncoder([
|
|
683
|
+
["numSignerAccounts", getMemoizedU8Encoder()],
|
|
684
|
+
["numReadonlySignerAccounts", getMemoizedU8Encoder()],
|
|
685
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8Encoder()]
|
|
686
|
+
]);
|
|
565
687
|
}
|
|
566
688
|
function getMessageHeaderDecoder() {
|
|
567
|
-
return getStructDecoder(
|
|
568
|
-
[
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
],
|
|
573
|
-
{
|
|
574
|
-
description: messageHeaderDescription
|
|
575
|
-
}
|
|
576
|
-
);
|
|
689
|
+
return getStructDecoder([
|
|
690
|
+
["numSignerAccounts", getMemoizedU8Decoder()],
|
|
691
|
+
["numReadonlySignerAccounts", getMemoizedU8Decoder()],
|
|
692
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8Decoder()]
|
|
693
|
+
]);
|
|
577
694
|
}
|
|
578
|
-
var programAddressIndexDescription = __DEV__ ? "The index of the program being called, according to the well-ordered accounts list for this transaction" : "programAddressIndex";
|
|
579
|
-
var accountIndexDescription = __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : void 0;
|
|
580
|
-
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";
|
|
581
|
-
var dataDescription = __DEV__ ? "An optional buffer of data passed to the instruction" : "data";
|
|
582
695
|
var memoizedGetInstructionEncoder;
|
|
583
696
|
function getInstructionEncoder() {
|
|
584
697
|
if (!memoizedGetInstructionEncoder) {
|
|
585
698
|
memoizedGetInstructionEncoder = mapEncoder(
|
|
586
699
|
getStructEncoder([
|
|
587
|
-
["programAddressIndex", getU8Encoder(
|
|
588
|
-
[
|
|
589
|
-
|
|
590
|
-
getArrayEncoder(getU8Encoder({ description: accountIndexDescription }), {
|
|
591
|
-
description: accountIndicesDescription,
|
|
592
|
-
size: getShortU16Encoder()
|
|
593
|
-
})
|
|
594
|
-
],
|
|
595
|
-
["data", getBytesEncoder({ description: dataDescription, size: getShortU16Encoder() })]
|
|
700
|
+
["programAddressIndex", getU8Encoder()],
|
|
701
|
+
["accountIndices", getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })],
|
|
702
|
+
["data", getBytesEncoder({ size: getShortU16Encoder() })]
|
|
596
703
|
]),
|
|
597
704
|
// Convert an instruction to have all fields defined
|
|
598
705
|
(instruction) => {
|
|
@@ -614,15 +721,9 @@ function getInstructionDecoder() {
|
|
|
614
721
|
if (!memoizedGetInstructionDecoder) {
|
|
615
722
|
memoizedGetInstructionDecoder = mapDecoder(
|
|
616
723
|
getStructDecoder([
|
|
617
|
-
["programAddressIndex", getU8Decoder(
|
|
618
|
-
[
|
|
619
|
-
|
|
620
|
-
getArrayDecoder(getU8Decoder({ description: accountIndexDescription }), {
|
|
621
|
-
description: accountIndicesDescription,
|
|
622
|
-
size: getShortU16Decoder()
|
|
623
|
-
})
|
|
624
|
-
],
|
|
625
|
-
["data", getBytesDecoder({ description: dataDescription, size: getShortU16Decoder() })]
|
|
724
|
+
["programAddressIndex", getU8Decoder()],
|
|
725
|
+
["accountIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })],
|
|
726
|
+
["data", getBytesDecoder({ size: getShortU16Decoder() })]
|
|
626
727
|
]),
|
|
627
728
|
// Convert an instruction to exclude optional fields if they are empty
|
|
628
729
|
(instruction) => {
|
|
@@ -641,47 +742,40 @@ function getInstructionDecoder() {
|
|
|
641
742
|
return memoizedGetInstructionDecoder;
|
|
642
743
|
}
|
|
643
744
|
var VERSION_FLAG_MASK = 128;
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
}
|
|
662
|
-
if (value < 0 || value > 127) {
|
|
663
|
-
throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
|
|
664
|
-
}
|
|
665
|
-
return new Uint8Array([value | VERSION_FLAG_MASK]);
|
|
745
|
+
function getTransactionVersionEncoder() {
|
|
746
|
+
return createEncoder({
|
|
747
|
+
getSizeFromValue: (value) => value === "legacy" ? 0 : 1,
|
|
748
|
+
maxSize: 1,
|
|
749
|
+
write: (value, bytes, offset) => {
|
|
750
|
+
if (value === "legacy") {
|
|
751
|
+
return offset;
|
|
752
|
+
}
|
|
753
|
+
if (value < 0 || value > 127) {
|
|
754
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_VERSION_NUMBER_OUT_OF_RANGE, {
|
|
755
|
+
actualVersion: value
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
bytes.set([value | VERSION_FLAG_MASK], offset);
|
|
759
|
+
return offset + 1;
|
|
760
|
+
}
|
|
761
|
+
});
|
|
666
762
|
}
|
|
667
763
|
function getTransactionVersionDecoder() {
|
|
668
|
-
return {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
764
|
+
return createDecoder({
|
|
765
|
+
maxSize: 1,
|
|
766
|
+
read: (bytes, offset) => {
|
|
767
|
+
const firstByte = bytes[offset];
|
|
768
|
+
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
769
|
+
return ["legacy", offset];
|
|
770
|
+
} else {
|
|
771
|
+
const version = firstByte ^ VERSION_FLAG_MASK;
|
|
772
|
+
return [version, offset + 1];
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
});
|
|
678
776
|
}
|
|
679
777
|
|
|
680
778
|
// src/serializers/message.ts
|
|
681
|
-
var staticAccountsDescription = __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "staticAccounts";
|
|
682
|
-
var lifetimeTokenDescription = __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "lifetimeToken";
|
|
683
|
-
var instructionsDescription = __DEV__ ? "A compact-array of instructions belonging to this transaction" : "instructions";
|
|
684
|
-
var addressTableLookupsDescription = __DEV__ ? "A compact array of address table lookups belonging to this transaction" : "addressTableLookups";
|
|
685
779
|
function getCompiledMessageLegacyEncoder() {
|
|
686
780
|
return getStructEncoder(getPreludeStructEncoderTuple());
|
|
687
781
|
}
|
|
@@ -706,91 +800,48 @@ function getPreludeStructEncoderTuple() {
|
|
|
706
800
|
return [
|
|
707
801
|
["version", getTransactionVersionEncoder()],
|
|
708
802
|
["header", getMessageHeaderEncoder()],
|
|
709
|
-
[
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
description: staticAccountsDescription,
|
|
713
|
-
size: getShortU16Encoder()
|
|
714
|
-
})
|
|
715
|
-
],
|
|
716
|
-
[
|
|
717
|
-
"lifetimeToken",
|
|
718
|
-
getStringEncoder({
|
|
719
|
-
description: lifetimeTokenDescription,
|
|
720
|
-
encoding: getBase58Encoder(),
|
|
721
|
-
size: 32
|
|
722
|
-
})
|
|
723
|
-
],
|
|
724
|
-
[
|
|
725
|
-
"instructions",
|
|
726
|
-
getArrayEncoder(getInstructionEncoder(), {
|
|
727
|
-
description: instructionsDescription,
|
|
728
|
-
size: getShortU16Encoder()
|
|
729
|
-
})
|
|
730
|
-
]
|
|
803
|
+
["staticAccounts", getArrayEncoder(getAddressEncoder(), { size: getShortU16Encoder() })],
|
|
804
|
+
["lifetimeToken", getStringEncoder({ encoding: getBase58Encoder(), size: 32 })],
|
|
805
|
+
["instructions", getArrayEncoder(getInstructionEncoder(), { size: getShortU16Encoder() })]
|
|
731
806
|
];
|
|
732
807
|
}
|
|
733
808
|
function getPreludeStructDecoderTuple() {
|
|
734
809
|
return [
|
|
735
810
|
["version", getTransactionVersionDecoder()],
|
|
736
811
|
["header", getMessageHeaderDecoder()],
|
|
737
|
-
[
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
description: staticAccountsDescription,
|
|
741
|
-
size: getShortU16Decoder()
|
|
742
|
-
})
|
|
743
|
-
],
|
|
744
|
-
[
|
|
745
|
-
"lifetimeToken",
|
|
746
|
-
getStringDecoder({
|
|
747
|
-
description: lifetimeTokenDescription,
|
|
748
|
-
encoding: getBase58Decoder(),
|
|
749
|
-
size: 32
|
|
750
|
-
})
|
|
751
|
-
],
|
|
752
|
-
[
|
|
753
|
-
"instructions",
|
|
754
|
-
getArrayDecoder(getInstructionDecoder(), {
|
|
755
|
-
description: instructionsDescription,
|
|
756
|
-
size: getShortU16Decoder()
|
|
757
|
-
})
|
|
758
|
-
],
|
|
812
|
+
["staticAccounts", getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() })],
|
|
813
|
+
["lifetimeToken", getStringDecoder({ encoding: getBase58Decoder(), size: 32 })],
|
|
814
|
+
["instructions", getArrayDecoder(getInstructionDecoder(), { size: getShortU16Decoder() })],
|
|
759
815
|
["addressTableLookups", getAddressTableLookupArrayDecoder()]
|
|
760
816
|
];
|
|
761
817
|
}
|
|
762
818
|
function getAddressTableLookupArrayEncoder() {
|
|
763
|
-
return getArrayEncoder(getAddressTableLookupEncoder(), {
|
|
764
|
-
description: addressTableLookupsDescription,
|
|
765
|
-
size: getShortU16Encoder()
|
|
766
|
-
});
|
|
819
|
+
return getArrayEncoder(getAddressTableLookupEncoder(), { size: getShortU16Encoder() });
|
|
767
820
|
}
|
|
768
821
|
function getAddressTableLookupArrayDecoder() {
|
|
769
|
-
return getArrayDecoder(getAddressTableLookupDecoder(), {
|
|
770
|
-
description: addressTableLookupsDescription,
|
|
771
|
-
size: getShortU16Decoder()
|
|
772
|
-
});
|
|
822
|
+
return getArrayDecoder(getAddressTableLookupDecoder(), { size: getShortU16Decoder() });
|
|
773
823
|
}
|
|
774
|
-
var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
|
|
775
824
|
function getCompiledMessageEncoder() {
|
|
776
|
-
return {
|
|
777
|
-
|
|
778
|
-
encode: (compiledMessage) => {
|
|
825
|
+
return createEncoder({
|
|
826
|
+
getSizeFromValue: (compiledMessage) => {
|
|
779
827
|
if (compiledMessage.version === "legacy") {
|
|
780
|
-
return getCompiledMessageLegacyEncoder().
|
|
828
|
+
return getCompiledMessageLegacyEncoder().getSizeFromValue(compiledMessage);
|
|
781
829
|
} else {
|
|
782
|
-
return getCompiledMessageVersionedEncoder().
|
|
830
|
+
return getCompiledMessageVersionedEncoder().getSizeFromValue(compiledMessage);
|
|
783
831
|
}
|
|
784
832
|
},
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
833
|
+
write: (compiledMessage, bytes, offset) => {
|
|
834
|
+
if (compiledMessage.version === "legacy") {
|
|
835
|
+
return getCompiledMessageLegacyEncoder().write(compiledMessage, bytes, offset);
|
|
836
|
+
} else {
|
|
837
|
+
return getCompiledMessageVersionedEncoder().write(compiledMessage, bytes, offset);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
});
|
|
788
841
|
}
|
|
789
842
|
function getCompiledMessageDecoder() {
|
|
790
843
|
return mapDecoder(
|
|
791
|
-
getStructDecoder(getPreludeStructDecoderTuple(),
|
|
792
|
-
description: messageDescription
|
|
793
|
-
}),
|
|
844
|
+
getStructDecoder(getPreludeStructDecoderTuple()),
|
|
794
845
|
({ addressTableLookups, ...restOfMessage }) => {
|
|
795
846
|
if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
|
|
796
847
|
return restOfMessage;
|
|
@@ -820,168 +871,36 @@ function getCompiledTransaction(transaction) {
|
|
|
820
871
|
signatures
|
|
821
872
|
};
|
|
822
873
|
}
|
|
823
|
-
function getAccountMetas(message) {
|
|
824
|
-
const { header } = message;
|
|
825
|
-
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
826
|
-
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
827
|
-
const accountMetas = [];
|
|
828
|
-
let accountIndex = 0;
|
|
829
|
-
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
830
|
-
accountMetas.push({
|
|
831
|
-
address: message.staticAccounts[accountIndex],
|
|
832
|
-
role: AccountRole.WRITABLE_SIGNER
|
|
833
|
-
});
|
|
834
|
-
accountIndex++;
|
|
835
|
-
}
|
|
836
|
-
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
837
|
-
accountMetas.push({
|
|
838
|
-
address: message.staticAccounts[accountIndex],
|
|
839
|
-
role: AccountRole.READONLY_SIGNER
|
|
840
|
-
});
|
|
841
|
-
accountIndex++;
|
|
842
|
-
}
|
|
843
|
-
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
844
|
-
accountMetas.push({
|
|
845
|
-
address: message.staticAccounts[accountIndex],
|
|
846
|
-
role: AccountRole.WRITABLE
|
|
847
|
-
});
|
|
848
|
-
accountIndex++;
|
|
849
|
-
}
|
|
850
|
-
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
851
|
-
accountMetas.push({
|
|
852
|
-
address: message.staticAccounts[accountIndex],
|
|
853
|
-
role: AccountRole.READONLY
|
|
854
|
-
});
|
|
855
|
-
accountIndex++;
|
|
856
|
-
}
|
|
857
|
-
return accountMetas;
|
|
858
|
-
}
|
|
859
|
-
function convertInstruction(instruction, accountMetas) {
|
|
860
|
-
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
861
|
-
if (!programAddress) {
|
|
862
|
-
throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
|
|
863
|
-
}
|
|
864
|
-
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
865
|
-
const { data } = instruction;
|
|
866
|
-
return {
|
|
867
|
-
programAddress,
|
|
868
|
-
...accounts && accounts.length ? { accounts } : {},
|
|
869
|
-
...data && data.length ? { data } : {}
|
|
870
|
-
};
|
|
871
|
-
}
|
|
872
|
-
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
873
|
-
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
874
|
-
return {
|
|
875
|
-
blockhash: messageLifetimeToken,
|
|
876
|
-
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
877
|
-
// U64 MAX
|
|
878
|
-
};
|
|
879
|
-
} else {
|
|
880
|
-
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
881
|
-
assertIsAddress(nonceAccountAddress);
|
|
882
|
-
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
883
|
-
assertIsAddress(nonceAuthorityAddress);
|
|
884
|
-
return {
|
|
885
|
-
nonce: messageLifetimeToken,
|
|
886
|
-
nonceAccountAddress,
|
|
887
|
-
nonceAuthorityAddress
|
|
888
|
-
};
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
function convertSignatures(compiledTransaction) {
|
|
892
|
-
const {
|
|
893
|
-
compiledMessage: { staticAccounts },
|
|
894
|
-
signatures
|
|
895
|
-
} = compiledTransaction;
|
|
896
|
-
return signatures.reduce((acc, sig, index) => {
|
|
897
|
-
const allZeros = sig.every((byte) => byte === 0);
|
|
898
|
-
if (allZeros)
|
|
899
|
-
return acc;
|
|
900
|
-
const address = staticAccounts[index];
|
|
901
|
-
return { ...acc, [address]: sig };
|
|
902
|
-
}, {});
|
|
903
|
-
}
|
|
904
|
-
function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
|
|
905
|
-
const { compiledMessage } = compiledTransaction;
|
|
906
|
-
if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
|
|
907
|
-
throw new Error("Cannot convert transaction with addressTableLookups");
|
|
908
|
-
}
|
|
909
|
-
const feePayer = compiledMessage.staticAccounts[0];
|
|
910
|
-
if (!feePayer)
|
|
911
|
-
throw new Error("No fee payer set in CompiledTransaction");
|
|
912
|
-
const accountMetas = getAccountMetas(compiledMessage);
|
|
913
|
-
const instructions = compiledMessage.instructions.map(
|
|
914
|
-
(compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
|
|
915
|
-
);
|
|
916
|
-
const firstInstruction = instructions[0];
|
|
917
|
-
const lifetimeConstraint = getLifetimeConstraint(
|
|
918
|
-
compiledMessage.lifetimeToken,
|
|
919
|
-
firstInstruction,
|
|
920
|
-
lastValidBlockHeight
|
|
921
|
-
);
|
|
922
|
-
const signatures = convertSignatures(compiledTransaction);
|
|
923
|
-
return pipe(
|
|
924
|
-
createTransaction({ version: compiledMessage.version }),
|
|
925
|
-
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
926
|
-
(tx) => instructions.reduce((acc, instruction) => {
|
|
927
|
-
return appendTransactionInstruction(instruction, acc);
|
|
928
|
-
}, tx),
|
|
929
|
-
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
930
|
-
(tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
|
|
931
|
-
);
|
|
932
|
-
}
|
|
933
874
|
|
|
934
875
|
// src/serializers/transaction.ts
|
|
935
|
-
var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
|
|
936
|
-
var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
|
|
937
876
|
function getCompiledTransactionEncoder() {
|
|
938
|
-
return getStructEncoder(
|
|
939
|
-
[
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
getArrayEncoder(getBytesEncoder({ size: 64 }), {
|
|
943
|
-
description: signaturesDescription,
|
|
944
|
-
size: getShortU16Encoder()
|
|
945
|
-
})
|
|
946
|
-
],
|
|
947
|
-
["compiledMessage", getCompiledMessageEncoder()]
|
|
948
|
-
],
|
|
949
|
-
{
|
|
950
|
-
description: transactionDescription
|
|
951
|
-
}
|
|
952
|
-
);
|
|
953
|
-
}
|
|
954
|
-
function getSignatureDecoder() {
|
|
955
|
-
return mapDecoder(getBytesDecoder({ size: 64 }), (bytes) => bytes);
|
|
877
|
+
return getStructEncoder([
|
|
878
|
+
["signatures", getArrayEncoder(getBytesEncoder({ size: 64 }), { size: getShortU16Encoder() })],
|
|
879
|
+
["compiledMessage", getCompiledMessageEncoder()]
|
|
880
|
+
]);
|
|
956
881
|
}
|
|
957
882
|
function getCompiledTransactionDecoder() {
|
|
958
|
-
return getStructDecoder(
|
|
883
|
+
return getStructDecoder([
|
|
959
884
|
[
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
size: getShortU16Decoder()
|
|
965
|
-
})
|
|
966
|
-
],
|
|
967
|
-
["compiledMessage", getCompiledMessageDecoder()]
|
|
885
|
+
"signatures",
|
|
886
|
+
getArrayDecoder(getBytesDecoder({ size: 64 }), {
|
|
887
|
+
size: getShortU16Decoder()
|
|
888
|
+
})
|
|
968
889
|
],
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
}
|
|
972
|
-
);
|
|
890
|
+
["compiledMessage", getCompiledMessageDecoder()]
|
|
891
|
+
]);
|
|
973
892
|
}
|
|
974
893
|
function getTransactionEncoder() {
|
|
975
894
|
return mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
|
|
976
895
|
}
|
|
977
|
-
function getTransactionDecoder(
|
|
896
|
+
function getTransactionDecoder(config) {
|
|
978
897
|
return mapDecoder(
|
|
979
898
|
getCompiledTransactionDecoder(),
|
|
980
|
-
(compiledTransaction) => decompileTransaction(compiledTransaction,
|
|
899
|
+
(compiledTransaction) => decompileTransaction(compiledTransaction, config)
|
|
981
900
|
);
|
|
982
901
|
}
|
|
983
|
-
function getTransactionCodec(
|
|
984
|
-
return combineCodec(getTransactionEncoder(), getTransactionDecoder(
|
|
902
|
+
function getTransactionCodec(config) {
|
|
903
|
+
return combineCodec(getTransactionEncoder(), getTransactionDecoder(config));
|
|
985
904
|
}
|
|
986
905
|
var base58Decoder;
|
|
987
906
|
function getSignatureFromTransaction(transaction) {
|
|
@@ -989,11 +908,9 @@ function getSignatureFromTransaction(transaction) {
|
|
|
989
908
|
base58Decoder = getBase58Decoder();
|
|
990
909
|
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
991
910
|
if (!signatureBytes) {
|
|
992
|
-
throw new
|
|
993
|
-
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
994
|
-
);
|
|
911
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_SIGNATURE_NOT_COMPUTABLE);
|
|
995
912
|
}
|
|
996
|
-
const transactionSignature = base58Decoder.decode(signatureBytes)
|
|
913
|
+
const transactionSignature = base58Decoder.decode(signatureBytes);
|
|
997
914
|
return transactionSignature;
|
|
998
915
|
}
|
|
999
916
|
async function partiallySignTransaction(keyPairs, transaction) {
|
|
@@ -1024,17 +941,23 @@ async function signTransaction(keyPairs, transaction) {
|
|
|
1024
941
|
function assertTransactionIsFullySigned(transaction) {
|
|
1025
942
|
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
|
|
1026
943
|
const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
|
|
944
|
+
const missingSigs = [];
|
|
1027
945
|
requiredSigners.forEach((address) => {
|
|
1028
946
|
if (!transaction.signatures[address]) {
|
|
1029
|
-
|
|
947
|
+
missingSigs.push(address);
|
|
1030
948
|
}
|
|
1031
949
|
});
|
|
950
|
+
if (missingSigs.length > 0) {
|
|
951
|
+
throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_SIGNATURES, {
|
|
952
|
+
addresses: missingSigs
|
|
953
|
+
});
|
|
954
|
+
}
|
|
1032
955
|
}
|
|
1033
956
|
function getBase64EncodedWireTransaction(transaction) {
|
|
1034
957
|
const wireTransactionBytes = getTransactionEncoder().encode(transaction);
|
|
1035
|
-
return getBase64Decoder().decode(wireTransactionBytes)
|
|
958
|
+
return getBase64Decoder().decode(wireTransactionBytes);
|
|
1036
959
|
}
|
|
1037
960
|
|
|
1038
|
-
export { appendTransactionInstruction,
|
|
961
|
+
export { appendTransactionInstruction, appendTransactionInstructions, assertIsDurableNonceTransaction, assertIsTransactionWithBlockhashLifetime, assertTransactionIsFullySigned, compileMessage, createTransaction, decompileTransaction, getBase64EncodedWireTransaction, getCompiledMessageCodec, getCompiledMessageDecoder, getCompiledMessageEncoder, getCompiledTransactionDecoder, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, getUnsignedTransaction, isAdvanceNonceAccountInstruction, partiallySignTransaction, prependTransactionInstruction, prependTransactionInstructions, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction };
|
|
1039
962
|
//# sourceMappingURL=out.js.map
|
|
1040
963
|
//# sourceMappingURL=index.browser.js.map
|