@solana/transactions 2.0.0-experimental.d32897d → 2.0.0-experimental.d3af599
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 +1 -43
- package/dist/index.browser.cjs +152 -188
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +149 -189
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +436 -431
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +149 -189
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +152 -188
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +149 -189
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +22 -20
- package/dist/types/accounts.d.ts +2 -2
- package/dist/types/accounts.d.ts.map +1 -0
- package/dist/types/blockhash.d.ts.map +1 -0
- package/dist/types/compilable-transaction.d.ts +7 -0
- package/dist/types/compilable-transaction.d.ts.map +1 -0
- package/dist/types/compile-address-table-lookups.d.ts +2 -2
- package/dist/types/compile-address-table-lookups.d.ts.map +1 -0
- package/dist/types/compile-header.d.ts.map +1 -0
- package/dist/types/compile-instructions.d.ts.map +1 -0
- package/dist/types/compile-lifetime-token.d.ts.map +1 -0
- package/dist/types/compile-static-accounts.d.ts +2 -2
- package/dist/types/compile-static-accounts.d.ts.map +1 -0
- package/dist/types/compile-transaction.d.ts +5 -6
- package/dist/types/compile-transaction.d.ts.map +1 -0
- package/dist/types/create-transaction.d.ts.map +1 -0
- package/dist/types/decompile-transaction.d.ts +2 -4
- package/dist/types/decompile-transaction.d.ts.map +1 -0
- package/dist/types/durable-nonce.d.ts +3 -3
- package/dist/types/durable-nonce.d.ts.map +1 -0
- package/dist/types/fee-payer.d.ts +4 -4
- package/dist/types/fee-payer.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/instructions.d.ts.map +1 -0
- package/dist/types/message.d.ts +1 -5
- package/dist/types/message.d.ts.map +1 -0
- package/dist/types/serializers/address-table-lookup.d.ts.map +1 -0
- package/dist/types/serializers/header.d.ts.map +1 -0
- package/dist/types/serializers/index.d.ts +1 -0
- package/dist/types/serializers/index.d.ts.map +1 -0
- package/dist/types/serializers/instruction.d.ts.map +1 -0
- package/dist/types/serializers/message.d.ts.map +1 -0
- package/dist/types/serializers/transaction-version.d.ts.map +1 -0
- package/dist/types/serializers/transaction.d.ts +1 -3
- package/dist/types/serializers/transaction.d.ts.map +1 -0
- package/dist/types/signatures.d.ts +8 -13
- package/dist/types/signatures.d.ts.map +1 -0
- package/dist/types/types.d.ts +6 -13
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/unsigned-transaction.d.ts.map +1 -0
- package/dist/types/wire-transaction.d.ts.map +1 -0
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -244,21 +244,11 @@ This type represents a transaction that is signed by all of its required signers
|
|
|
244
244
|
|
|
245
245
|
Expect any function that modifies a transaction (eg. `setTransactionFeePayer`, `appendTransactionInstruction`, et cetera) to delete a transaction's `signatures` property and unset this type.
|
|
246
246
|
|
|
247
|
-
#### `TransactionSignature`
|
|
248
|
-
|
|
249
|
-
This type represents the base58-encoded signature of a transactions fee payer. This value uniquely identifies the transaction on the network.
|
|
250
|
-
|
|
251
247
|
### Functions
|
|
252
248
|
|
|
253
|
-
#### `assertIsTransactionSignature()`
|
|
254
|
-
|
|
255
|
-
From time to time you might acquire a string that you expect to be the base58-encoded signature of a transaction, from an untrusted network API or user input. To assert that such an arbitrary string is in fact a transaction signature, use the `assertIsTransactionSignature` function.
|
|
256
|
-
|
|
257
|
-
See [`assertIsBlockhash()`](#assertisblockhash) for an example of how to use an assertion function.
|
|
258
|
-
|
|
259
249
|
#### `getSignatureFromTransaction()`
|
|
260
250
|
|
|
261
|
-
Given a transaction signed by its fee payer, this method will return the `
|
|
251
|
+
Given a transaction signed by its fee payer, this method will return the `Signature` that uniquely identifies it. This string can be used to look up transactions at a later date, for example on a Solana block explorer.
|
|
262
252
|
|
|
263
253
|
```ts
|
|
264
254
|
import { getSignatureFromTransaction } from '@solana/transactions';
|
|
@@ -267,25 +257,6 @@ const signature = getSignatureFromTransaction(tx);
|
|
|
267
257
|
console.debug(`Inspect this transaction at https://explorer.solana.com/tx/${signature}`);
|
|
268
258
|
```
|
|
269
259
|
|
|
270
|
-
#### `isTransactionSignature()`
|
|
271
|
-
|
|
272
|
-
This is a type guard that accepts a string as input. It will both return `true` if the string conforms to the `TransactionSignature` type and will refine the type for use in your program.
|
|
273
|
-
|
|
274
|
-
```ts
|
|
275
|
-
import { isTransactionSignature } from '@solana/transactions';
|
|
276
|
-
|
|
277
|
-
if (isTransactionSignature(signature)) {
|
|
278
|
-
// At this point, `signature` has been refined to a
|
|
279
|
-
// `TransactionSignature` that can be used with the RPC.
|
|
280
|
-
const {
|
|
281
|
-
value: [status],
|
|
282
|
-
} = await rpc.getSignatureStatuses([signature]).send();
|
|
283
|
-
setSignatureStatus(status);
|
|
284
|
-
} else {
|
|
285
|
-
setError(`${signature} is not a transaction signature`);
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
260
|
#### `signTransaction()`
|
|
290
261
|
|
|
291
262
|
Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are required to sign a transaction, this method will return a new signed transaction having the same type as the one supplied plus the `ITransactionWithSignatures` type.
|
|
@@ -297,19 +268,6 @@ import { signTransaction } from '@solana/transactions';
|
|
|
297
268
|
const signedTransaction = await signTransaction([myPrivateKey], tx);
|
|
298
269
|
```
|
|
299
270
|
|
|
300
|
-
#### `transactionSignature()`
|
|
301
|
-
|
|
302
|
-
This helper combines _asserting_ that a string is a transaction signature with _coercing_ it to the `TransactionSignature` type. It's best used with untrusted input.
|
|
303
|
-
|
|
304
|
-
```ts
|
|
305
|
-
import { transactionSignature } from '@solana/transactions';
|
|
306
|
-
|
|
307
|
-
const signature = transactionSignature(userSuppliedSignature);
|
|
308
|
-
const {
|
|
309
|
-
value: [status],
|
|
310
|
-
} = await rpc.getSignatureStatuses([signature]).send();
|
|
311
|
-
```
|
|
312
|
-
|
|
313
271
|
## Serializing transactions
|
|
314
272
|
|
|
315
273
|
Before sending a transaction to be landed on the network, you must serialize it in a particular way. You can use these types and functions to serialize a signed transaction into a binary format suitable for transit over the wire.
|
package/dist/index.browser.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var codecsStrings = require('@solana/codecs-strings');
|
|
4
|
+
var addresses = require('@solana/addresses');
|
|
4
5
|
var codecsCore = require('@solana/codecs-core');
|
|
5
6
|
var codecsDataStructures = require('@solana/codecs-data-structures');
|
|
6
7
|
var codecsNumbers = require('@solana/codecs-numbers');
|
|
7
|
-
var addresses = require('@solana/addresses');
|
|
8
8
|
var functional = require('@solana/functional');
|
|
9
9
|
var keys = require('@solana/keys');
|
|
10
10
|
|
|
@@ -254,7 +254,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
254
254
|
const shouldReplaceEntry = (
|
|
255
255
|
// Consider using the new LOOKUP_TABLE if its address is different...
|
|
256
256
|
entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
|
|
257
|
-
(addressComparator
|
|
257
|
+
(addressComparator ||= addresses.getAddressComparator())(
|
|
258
258
|
accountMeta.lookupTableAddress,
|
|
259
259
|
entry.lookupTableAddress
|
|
260
260
|
) < 0
|
|
@@ -360,7 +360,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
360
360
|
if (leftIsWritable !== isWritableRole(rightEntry.role)) {
|
|
361
361
|
return leftIsWritable ? -1 : 1;
|
|
362
362
|
}
|
|
363
|
-
addressComparator
|
|
363
|
+
addressComparator ||= addresses.getAddressComparator();
|
|
364
364
|
if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
|
|
365
365
|
return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
|
|
366
366
|
} else {
|
|
@@ -373,16 +373,15 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
373
373
|
return orderedAccounts;
|
|
374
374
|
}
|
|
375
375
|
function getCompiledAddressTableLookups(orderedAccounts) {
|
|
376
|
-
var _a;
|
|
377
376
|
const index = {};
|
|
378
377
|
for (const account of orderedAccounts) {
|
|
379
378
|
if (!("lookupTableAddress" in account)) {
|
|
380
379
|
continue;
|
|
381
380
|
}
|
|
382
|
-
const entry = index[
|
|
381
|
+
const entry = index[account.lookupTableAddress] ||= {
|
|
383
382
|
readableIndices: [],
|
|
384
383
|
writableIndices: []
|
|
385
|
-
}
|
|
384
|
+
};
|
|
386
385
|
if (account.role === AccountRole.WRITABLE) {
|
|
387
386
|
entry.writableIndices.push(account.addressIndex);
|
|
388
387
|
} else {
|
|
@@ -468,134 +467,6 @@ function compileMessage(transaction) {
|
|
|
468
467
|
version: transaction.version
|
|
469
468
|
};
|
|
470
469
|
}
|
|
471
|
-
|
|
472
|
-
// src/compile-transaction.ts
|
|
473
|
-
function getCompiledTransaction(transaction) {
|
|
474
|
-
const compiledMessage = compileMessage(transaction);
|
|
475
|
-
let signatures;
|
|
476
|
-
if ("signatures" in transaction) {
|
|
477
|
-
signatures = [];
|
|
478
|
-
for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
|
|
479
|
-
signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
|
|
480
|
-
}
|
|
481
|
-
} else {
|
|
482
|
-
signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
|
|
483
|
-
}
|
|
484
|
-
return {
|
|
485
|
-
compiledMessage,
|
|
486
|
-
signatures
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
function getAccountMetas(message) {
|
|
490
|
-
const { header } = message;
|
|
491
|
-
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
492
|
-
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
493
|
-
const accountMetas = [];
|
|
494
|
-
let accountIndex = 0;
|
|
495
|
-
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
496
|
-
accountMetas.push({
|
|
497
|
-
address: message.staticAccounts[accountIndex],
|
|
498
|
-
role: AccountRole.WRITABLE_SIGNER
|
|
499
|
-
});
|
|
500
|
-
accountIndex++;
|
|
501
|
-
}
|
|
502
|
-
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
503
|
-
accountMetas.push({
|
|
504
|
-
address: message.staticAccounts[accountIndex],
|
|
505
|
-
role: AccountRole.READONLY_SIGNER
|
|
506
|
-
});
|
|
507
|
-
accountIndex++;
|
|
508
|
-
}
|
|
509
|
-
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
510
|
-
accountMetas.push({
|
|
511
|
-
address: message.staticAccounts[accountIndex],
|
|
512
|
-
role: AccountRole.WRITABLE
|
|
513
|
-
});
|
|
514
|
-
accountIndex++;
|
|
515
|
-
}
|
|
516
|
-
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
517
|
-
accountMetas.push({
|
|
518
|
-
address: message.staticAccounts[accountIndex],
|
|
519
|
-
role: AccountRole.READONLY
|
|
520
|
-
});
|
|
521
|
-
accountIndex++;
|
|
522
|
-
}
|
|
523
|
-
return accountMetas;
|
|
524
|
-
}
|
|
525
|
-
function convertInstruction(instruction, accountMetas) {
|
|
526
|
-
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
527
|
-
if (!programAddress) {
|
|
528
|
-
throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
|
|
529
|
-
}
|
|
530
|
-
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
531
|
-
const { data } = instruction;
|
|
532
|
-
return {
|
|
533
|
-
programAddress,
|
|
534
|
-
...accounts && accounts.length ? { accounts } : {},
|
|
535
|
-
...data && data.length ? { data } : {}
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
539
|
-
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
540
|
-
return {
|
|
541
|
-
blockhash: messageLifetimeToken,
|
|
542
|
-
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
543
|
-
// U64 MAX
|
|
544
|
-
};
|
|
545
|
-
} else {
|
|
546
|
-
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
547
|
-
addresses.assertIsAddress(nonceAccountAddress);
|
|
548
|
-
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
549
|
-
addresses.assertIsAddress(nonceAuthorityAddress);
|
|
550
|
-
return {
|
|
551
|
-
nonce: messageLifetimeToken,
|
|
552
|
-
nonceAccountAddress,
|
|
553
|
-
nonceAuthorityAddress
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
function convertSignatures(compiledTransaction) {
|
|
558
|
-
const {
|
|
559
|
-
compiledMessage: { staticAccounts },
|
|
560
|
-
signatures
|
|
561
|
-
} = compiledTransaction;
|
|
562
|
-
return signatures.reduce((acc, sig, index) => {
|
|
563
|
-
const allZeros = sig.every((byte) => byte === 0);
|
|
564
|
-
if (allZeros)
|
|
565
|
-
return acc;
|
|
566
|
-
const address = staticAccounts[index];
|
|
567
|
-
return { ...acc, [address]: sig };
|
|
568
|
-
}, {});
|
|
569
|
-
}
|
|
570
|
-
function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
|
|
571
|
-
const { compiledMessage } = compiledTransaction;
|
|
572
|
-
if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
|
|
573
|
-
throw new Error("Cannot convert transaction with addressTableLookups");
|
|
574
|
-
}
|
|
575
|
-
const feePayer = compiledMessage.staticAccounts[0];
|
|
576
|
-
if (!feePayer)
|
|
577
|
-
throw new Error("No fee payer set in CompiledTransaction");
|
|
578
|
-
const accountMetas = getAccountMetas(compiledMessage);
|
|
579
|
-
const instructions = compiledMessage.instructions.map(
|
|
580
|
-
(compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
|
|
581
|
-
);
|
|
582
|
-
const firstInstruction = instructions[0];
|
|
583
|
-
const lifetimeConstraint = getLifetimeConstraint(
|
|
584
|
-
compiledMessage.lifetimeToken,
|
|
585
|
-
firstInstruction,
|
|
586
|
-
lastValidBlockHeight
|
|
587
|
-
);
|
|
588
|
-
const signatures = convertSignatures(compiledTransaction);
|
|
589
|
-
return functional.pipe(
|
|
590
|
-
createTransaction({ version: compiledMessage.version }),
|
|
591
|
-
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
592
|
-
(tx) => instructions.reduce((acc, instruction) => {
|
|
593
|
-
return appendTransactionInstruction(instruction, acc);
|
|
594
|
-
}, tx),
|
|
595
|
-
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
596
|
-
(tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
|
|
597
|
-
);
|
|
598
|
-
}
|
|
599
470
|
var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
|
|
600
471
|
var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
|
|
601
472
|
var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
|
|
@@ -930,6 +801,137 @@ function getCompiledMessageDecoder() {
|
|
|
930
801
|
}
|
|
931
802
|
);
|
|
932
803
|
}
|
|
804
|
+
function getCompiledMessageCodec() {
|
|
805
|
+
return codecsCore.combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// src/compile-transaction.ts
|
|
809
|
+
function getCompiledTransaction(transaction) {
|
|
810
|
+
const compiledMessage = compileMessage(transaction);
|
|
811
|
+
let signatures;
|
|
812
|
+
if ("signatures" in transaction) {
|
|
813
|
+
signatures = [];
|
|
814
|
+
for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
|
|
815
|
+
signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
|
|
816
|
+
}
|
|
817
|
+
} else {
|
|
818
|
+
signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
|
|
819
|
+
}
|
|
820
|
+
return {
|
|
821
|
+
compiledMessage,
|
|
822
|
+
signatures
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
function getAccountMetas(message) {
|
|
826
|
+
const { header } = message;
|
|
827
|
+
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
828
|
+
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
829
|
+
const accountMetas = [];
|
|
830
|
+
let accountIndex = 0;
|
|
831
|
+
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
832
|
+
accountMetas.push({
|
|
833
|
+
address: message.staticAccounts[accountIndex],
|
|
834
|
+
role: AccountRole.WRITABLE_SIGNER
|
|
835
|
+
});
|
|
836
|
+
accountIndex++;
|
|
837
|
+
}
|
|
838
|
+
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
839
|
+
accountMetas.push({
|
|
840
|
+
address: message.staticAccounts[accountIndex],
|
|
841
|
+
role: AccountRole.READONLY_SIGNER
|
|
842
|
+
});
|
|
843
|
+
accountIndex++;
|
|
844
|
+
}
|
|
845
|
+
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
846
|
+
accountMetas.push({
|
|
847
|
+
address: message.staticAccounts[accountIndex],
|
|
848
|
+
role: AccountRole.WRITABLE
|
|
849
|
+
});
|
|
850
|
+
accountIndex++;
|
|
851
|
+
}
|
|
852
|
+
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
853
|
+
accountMetas.push({
|
|
854
|
+
address: message.staticAccounts[accountIndex],
|
|
855
|
+
role: AccountRole.READONLY
|
|
856
|
+
});
|
|
857
|
+
accountIndex++;
|
|
858
|
+
}
|
|
859
|
+
return accountMetas;
|
|
860
|
+
}
|
|
861
|
+
function convertInstruction(instruction, accountMetas) {
|
|
862
|
+
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
863
|
+
if (!programAddress) {
|
|
864
|
+
throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
|
|
865
|
+
}
|
|
866
|
+
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
867
|
+
const { data } = instruction;
|
|
868
|
+
return {
|
|
869
|
+
programAddress,
|
|
870
|
+
...accounts && accounts.length ? { accounts } : {},
|
|
871
|
+
...data && data.length ? { data } : {}
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
875
|
+
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
876
|
+
return {
|
|
877
|
+
blockhash: messageLifetimeToken,
|
|
878
|
+
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
879
|
+
// U64 MAX
|
|
880
|
+
};
|
|
881
|
+
} else {
|
|
882
|
+
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
883
|
+
addresses.assertIsAddress(nonceAccountAddress);
|
|
884
|
+
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
885
|
+
addresses.assertIsAddress(nonceAuthorityAddress);
|
|
886
|
+
return {
|
|
887
|
+
nonce: messageLifetimeToken,
|
|
888
|
+
nonceAccountAddress,
|
|
889
|
+
nonceAuthorityAddress
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
function convertSignatures(compiledTransaction) {
|
|
894
|
+
const {
|
|
895
|
+
compiledMessage: { staticAccounts },
|
|
896
|
+
signatures
|
|
897
|
+
} = compiledTransaction;
|
|
898
|
+
return signatures.reduce((acc, sig, index) => {
|
|
899
|
+
const allZeros = sig.every((byte) => byte === 0);
|
|
900
|
+
if (allZeros)
|
|
901
|
+
return acc;
|
|
902
|
+
const address = staticAccounts[index];
|
|
903
|
+
return { ...acc, [address]: sig };
|
|
904
|
+
}, {});
|
|
905
|
+
}
|
|
906
|
+
function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
|
|
907
|
+
const { compiledMessage } = compiledTransaction;
|
|
908
|
+
if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
|
|
909
|
+
throw new Error("Cannot convert transaction with addressTableLookups");
|
|
910
|
+
}
|
|
911
|
+
const feePayer = compiledMessage.staticAccounts[0];
|
|
912
|
+
if (!feePayer)
|
|
913
|
+
throw new Error("No fee payer set in CompiledTransaction");
|
|
914
|
+
const accountMetas = getAccountMetas(compiledMessage);
|
|
915
|
+
const instructions = compiledMessage.instructions.map(
|
|
916
|
+
(compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
|
|
917
|
+
);
|
|
918
|
+
const firstInstruction = instructions[0];
|
|
919
|
+
const lifetimeConstraint = getLifetimeConstraint(
|
|
920
|
+
compiledMessage.lifetimeToken,
|
|
921
|
+
firstInstruction,
|
|
922
|
+
lastValidBlockHeight
|
|
923
|
+
);
|
|
924
|
+
const signatures = convertSignatures(compiledTransaction);
|
|
925
|
+
return functional.pipe(
|
|
926
|
+
createTransaction({ version: compiledMessage.version }),
|
|
927
|
+
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
928
|
+
(tx) => instructions.reduce((acc, instruction) => {
|
|
929
|
+
return appendTransactionInstruction(instruction, acc);
|
|
930
|
+
}, tx),
|
|
931
|
+
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
932
|
+
(tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
|
|
933
|
+
);
|
|
934
|
+
}
|
|
933
935
|
|
|
934
936
|
// src/serializers/transaction.ts
|
|
935
937
|
var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
|
|
@@ -983,47 +985,7 @@ function getTransactionDecoder(lastValidBlockHeight) {
|
|
|
983
985
|
function getTransactionCodec(lastValidBlockHeight) {
|
|
984
986
|
return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
|
|
985
987
|
}
|
|
986
|
-
var base58Encoder2;
|
|
987
988
|
var base58Decoder;
|
|
988
|
-
function assertIsTransactionSignature(putativeTransactionSignature) {
|
|
989
|
-
if (!base58Encoder2)
|
|
990
|
-
base58Encoder2 = codecsStrings.getBase58Encoder();
|
|
991
|
-
try {
|
|
992
|
-
if (
|
|
993
|
-
// Lowest value (64 bytes of zeroes)
|
|
994
|
-
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
995
|
-
putativeTransactionSignature.length > 88
|
|
996
|
-
) {
|
|
997
|
-
throw new Error("Expected input string to decode to a byte array of length 64.");
|
|
998
|
-
}
|
|
999
|
-
const bytes = base58Encoder2.encode(putativeTransactionSignature);
|
|
1000
|
-
const numBytes = bytes.byteLength;
|
|
1001
|
-
if (numBytes !== 64) {
|
|
1002
|
-
throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
|
|
1003
|
-
}
|
|
1004
|
-
} catch (e) {
|
|
1005
|
-
throw new Error(`\`${putativeTransactionSignature}\` is not a transaction signature`, {
|
|
1006
|
-
cause: e
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
function isTransactionSignature(putativeTransactionSignature) {
|
|
1011
|
-
if (!base58Encoder2)
|
|
1012
|
-
base58Encoder2 = codecsStrings.getBase58Encoder();
|
|
1013
|
-
if (
|
|
1014
|
-
// Lowest value (64 bytes of zeroes)
|
|
1015
|
-
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
1016
|
-
putativeTransactionSignature.length > 88
|
|
1017
|
-
) {
|
|
1018
|
-
return false;
|
|
1019
|
-
}
|
|
1020
|
-
const bytes = base58Encoder2.encode(putativeTransactionSignature);
|
|
1021
|
-
const numBytes = bytes.byteLength;
|
|
1022
|
-
if (numBytes !== 64) {
|
|
1023
|
-
return false;
|
|
1024
|
-
}
|
|
1025
|
-
return true;
|
|
1026
|
-
}
|
|
1027
989
|
function getSignatureFromTransaction(transaction) {
|
|
1028
990
|
if (!base58Decoder)
|
|
1029
991
|
base58Decoder = codecsStrings.getBase58Decoder();
|
|
@@ -1033,10 +995,10 @@ function getSignatureFromTransaction(transaction) {
|
|
|
1033
995
|
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
1034
996
|
);
|
|
1035
997
|
}
|
|
1036
|
-
const
|
|
1037
|
-
return
|
|
998
|
+
const transactionSignature = base58Decoder.decode(signatureBytes)[0];
|
|
999
|
+
return transactionSignature;
|
|
1038
1000
|
}
|
|
1039
|
-
async function
|
|
1001
|
+
async function partiallySignTransaction(keyPairs, transaction) {
|
|
1040
1002
|
const compiledMessage = compileMessage(transaction);
|
|
1041
1003
|
const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
|
|
1042
1004
|
const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
|
|
@@ -1055,9 +1017,11 @@ async function signTransaction(keyPairs, transaction) {
|
|
|
1055
1017
|
Object.freeze(out);
|
|
1056
1018
|
return out;
|
|
1057
1019
|
}
|
|
1058
|
-
function
|
|
1059
|
-
|
|
1060
|
-
|
|
1020
|
+
async function signTransaction(keyPairs, transaction) {
|
|
1021
|
+
const out = await partiallySignTransaction(keyPairs, transaction);
|
|
1022
|
+
assertTransactionIsFullySigned(out);
|
|
1023
|
+
Object.freeze(out);
|
|
1024
|
+
return out;
|
|
1061
1025
|
}
|
|
1062
1026
|
function assertTransactionIsFullySigned(transaction) {
|
|
1063
1027
|
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
|
|
@@ -1068,31 +1032,31 @@ function assertTransactionIsFullySigned(transaction) {
|
|
|
1068
1032
|
}
|
|
1069
1033
|
});
|
|
1070
1034
|
}
|
|
1071
|
-
|
|
1072
|
-
// src/wire-transaction.ts
|
|
1073
1035
|
function getBase64EncodedWireTransaction(transaction) {
|
|
1074
1036
|
const wireTransactionBytes = getTransactionEncoder().encode(transaction);
|
|
1075
|
-
|
|
1076
|
-
return btoa(String.fromCharCode(...wireTransactionBytes));
|
|
1077
|
-
}
|
|
1037
|
+
return codecsStrings.getBase64Decoder().decode(wireTransactionBytes)[0];
|
|
1078
1038
|
}
|
|
1079
1039
|
|
|
1080
1040
|
exports.appendTransactionInstruction = appendTransactionInstruction;
|
|
1081
1041
|
exports.assertIsBlockhash = assertIsBlockhash;
|
|
1082
1042
|
exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
|
|
1083
|
-
exports.assertIsTransactionSignature = assertIsTransactionSignature;
|
|
1084
1043
|
exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
|
|
1044
|
+
exports.compileMessage = compileMessage;
|
|
1085
1045
|
exports.createTransaction = createTransaction;
|
|
1086
1046
|
exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
|
|
1047
|
+
exports.getCompiledMessageCodec = getCompiledMessageCodec;
|
|
1048
|
+
exports.getCompiledMessageDecoder = getCompiledMessageDecoder;
|
|
1049
|
+
exports.getCompiledMessageEncoder = getCompiledMessageEncoder;
|
|
1087
1050
|
exports.getSignatureFromTransaction = getSignatureFromTransaction;
|
|
1088
1051
|
exports.getTransactionCodec = getTransactionCodec;
|
|
1089
1052
|
exports.getTransactionDecoder = getTransactionDecoder;
|
|
1090
1053
|
exports.getTransactionEncoder = getTransactionEncoder;
|
|
1091
1054
|
exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
|
|
1092
|
-
exports.
|
|
1055
|
+
exports.partiallySignTransaction = partiallySignTransaction;
|
|
1093
1056
|
exports.prependTransactionInstruction = prependTransactionInstruction;
|
|
1094
1057
|
exports.setTransactionFeePayer = setTransactionFeePayer;
|
|
1095
1058
|
exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
|
|
1096
1059
|
exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
|
|
1097
1060
|
exports.signTransaction = signTransaction;
|
|
1098
|
-
|
|
1061
|
+
//# sourceMappingURL=out.js.map
|
|
1062
|
+
//# sourceMappingURL=index.browser.cjs.map
|