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