@solana/transactions 2.0.0-experimental.6910664 → 2.0.0-experimental.699bde0
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 +24 -66
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +26 -64
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +477 -549
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +26 -64
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +26 -66
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +24 -64
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +18 -20
- package/dist/types/accounts.d.ts +2 -2
- package/dist/types/compilable-transaction.d.ts +7 -0
- package/dist/types/compile-address-table-lookups.d.ts +2 -2
- package/dist/types/compile-static-accounts.d.ts +2 -2
- package/dist/types/compile-transaction.d.ts +5 -6
- package/dist/types/decompile-transaction.d.ts +2 -4
- package/dist/types/durable-nonce.d.ts +3 -3
- package/dist/types/fee-payer.d.ts +4 -4
- package/dist/types/index.d.ts +1 -0
- package/dist/types/message.d.ts +1 -5
- package/dist/types/serializers/transaction.d.ts +1 -3
- package/dist/types/signatures.d.ts +8 -13
- package/dist/types/types.d.ts +6 -13
- package/package.json +13 -14
- package/dist/types/accounts.d.ts.map +0 -1
- package/dist/types/blockhash.d.ts.map +0 -1
- package/dist/types/compile-address-table-lookups.d.ts.map +0 -1
- package/dist/types/compile-header.d.ts.map +0 -1
- package/dist/types/compile-instructions.d.ts.map +0 -1
- package/dist/types/compile-lifetime-token.d.ts.map +0 -1
- package/dist/types/compile-static-accounts.d.ts.map +0 -1
- package/dist/types/compile-transaction.d.ts.map +0 -1
- package/dist/types/create-transaction.d.ts.map +0 -1
- package/dist/types/decompile-transaction.d.ts.map +0 -1
- package/dist/types/durable-nonce.d.ts.map +0 -1
- package/dist/types/fee-payer.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/instructions.d.ts.map +0 -1
- package/dist/types/message.d.ts.map +0 -1
- package/dist/types/serializers/address-table-lookup.d.ts.map +0 -1
- package/dist/types/serializers/header.d.ts.map +0 -1
- package/dist/types/serializers/index.d.ts.map +0 -1
- package/dist/types/serializers/instruction.d.ts.map +0 -1
- package/dist/types/serializers/message.d.ts.map +0 -1
- package/dist/types/serializers/transaction-version.d.ts.map +0 -1
- package/dist/types/serializers/transaction.d.ts.map +0 -1
- package/dist/types/signatures.d.ts.map +0 -1
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/unsigned-transaction.d.ts.map +0 -1
- package/dist/types/wire-transaction.d.ts.map +0 -1
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,12 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var codecsStrings = require('@solana/codecs-strings');
|
|
4
4
|
var codecsCore = require('@solana/codecs-core');
|
|
5
5
|
var codecsDataStructures = require('@solana/codecs-data-structures');
|
|
6
6
|
var codecsNumbers = require('@solana/codecs-numbers');
|
|
7
7
|
var addresses = require('@solana/addresses');
|
|
8
8
|
var functional = require('@solana/functional');
|
|
9
|
-
var codecsStrings = require('@solana/codecs-strings');
|
|
10
9
|
var keys = require('@solana/keys');
|
|
11
10
|
|
|
12
11
|
// ../build-scripts/env-shim.ts
|
|
@@ -27,7 +26,10 @@ function getUnsignedTransaction(transaction) {
|
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
// src/blockhash.ts
|
|
29
|
+
var base58Encoder;
|
|
30
30
|
function assertIsBlockhash(putativeBlockhash) {
|
|
31
|
+
if (!base58Encoder)
|
|
32
|
+
base58Encoder = codecsStrings.getBase58Encoder();
|
|
31
33
|
try {
|
|
32
34
|
if (
|
|
33
35
|
// Lowest value (32 bytes of zeroes)
|
|
@@ -36,7 +38,7 @@ function assertIsBlockhash(putativeBlockhash) {
|
|
|
36
38
|
) {
|
|
37
39
|
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
38
40
|
}
|
|
39
|
-
const bytes =
|
|
41
|
+
const bytes = base58Encoder.encode(putativeBlockhash);
|
|
40
42
|
const numBytes = bytes.byteLength;
|
|
41
43
|
if (numBytes !== 32) {
|
|
42
44
|
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
@@ -252,7 +254,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
252
254
|
const shouldReplaceEntry = (
|
|
253
255
|
// Consider using the new LOOKUP_TABLE if its address is different...
|
|
254
256
|
entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
|
|
255
|
-
(addressComparator
|
|
257
|
+
(addressComparator ||= addresses.getAddressComparator())(
|
|
256
258
|
accountMeta.lookupTableAddress,
|
|
257
259
|
entry.lookupTableAddress
|
|
258
260
|
) < 0
|
|
@@ -358,7 +360,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
358
360
|
if (leftIsWritable !== isWritableRole(rightEntry.role)) {
|
|
359
361
|
return leftIsWritable ? -1 : 1;
|
|
360
362
|
}
|
|
361
|
-
addressComparator
|
|
363
|
+
addressComparator ||= addresses.getAddressComparator();
|
|
362
364
|
if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
|
|
363
365
|
return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
|
|
364
366
|
} else {
|
|
@@ -371,16 +373,15 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
371
373
|
return orderedAccounts;
|
|
372
374
|
}
|
|
373
375
|
function getCompiledAddressTableLookups(orderedAccounts) {
|
|
374
|
-
var _a;
|
|
375
376
|
const index = {};
|
|
376
377
|
for (const account of orderedAccounts) {
|
|
377
378
|
if (!("lookupTableAddress" in account)) {
|
|
378
379
|
continue;
|
|
379
380
|
}
|
|
380
|
-
const entry = index[
|
|
381
|
+
const entry = index[account.lookupTableAddress] ||= {
|
|
381
382
|
readableIndices: [],
|
|
382
383
|
writableIndices: []
|
|
383
|
-
}
|
|
384
|
+
};
|
|
384
385
|
if (account.role === AccountRole.WRITABLE) {
|
|
385
386
|
entry.writableIndices.push(account.addressIndex);
|
|
386
387
|
} else {
|
|
@@ -981,65 +982,26 @@ function getTransactionDecoder(lastValidBlockHeight) {
|
|
|
981
982
|
function getTransactionCodec(lastValidBlockHeight) {
|
|
982
983
|
return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
|
|
983
984
|
}
|
|
984
|
-
|
|
985
|
-
try {
|
|
986
|
-
if (
|
|
987
|
-
// Lowest value (64 bytes of zeroes)
|
|
988
|
-
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
989
|
-
putativeTransactionSignature.length > 88
|
|
990
|
-
) {
|
|
991
|
-
throw new Error("Expected input string to decode to a byte array of length 64.");
|
|
992
|
-
}
|
|
993
|
-
const bytes = umiSerializers.base58.serialize(putativeTransactionSignature);
|
|
994
|
-
const numBytes = bytes.byteLength;
|
|
995
|
-
if (numBytes !== 64) {
|
|
996
|
-
throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
|
|
997
|
-
}
|
|
998
|
-
} catch (e) {
|
|
999
|
-
throw new Error(`\`${putativeTransactionSignature}\` is not a transaction signature`, {
|
|
1000
|
-
cause: e
|
|
1001
|
-
});
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
function isTransactionSignature(putativeTransactionSignature) {
|
|
1005
|
-
if (
|
|
1006
|
-
// Lowest value (64 bytes of zeroes)
|
|
1007
|
-
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
1008
|
-
putativeTransactionSignature.length > 88
|
|
1009
|
-
) {
|
|
1010
|
-
return false;
|
|
1011
|
-
}
|
|
1012
|
-
const bytes = umiSerializers.base58.serialize(putativeTransactionSignature);
|
|
1013
|
-
const numBytes = bytes.byteLength;
|
|
1014
|
-
if (numBytes !== 64) {
|
|
1015
|
-
return false;
|
|
1016
|
-
}
|
|
1017
|
-
return true;
|
|
1018
|
-
}
|
|
1019
|
-
async function getCompiledMessageSignature(message, secretKey) {
|
|
1020
|
-
const wireMessageBytes = getCompiledMessageEncoder().encode(message);
|
|
1021
|
-
const signature = await keys.signBytes(secretKey, wireMessageBytes);
|
|
1022
|
-
return signature;
|
|
1023
|
-
}
|
|
985
|
+
var base58Decoder;
|
|
1024
986
|
function getSignatureFromTransaction(transaction) {
|
|
987
|
+
if (!base58Decoder)
|
|
988
|
+
base58Decoder = codecsStrings.getBase58Decoder();
|
|
1025
989
|
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
1026
990
|
if (!signatureBytes) {
|
|
1027
991
|
throw new Error(
|
|
1028
992
|
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
1029
993
|
);
|
|
1030
994
|
}
|
|
1031
|
-
const
|
|
1032
|
-
return
|
|
995
|
+
const transactionSignature = base58Decoder.decode(signatureBytes)[0];
|
|
996
|
+
return transactionSignature;
|
|
1033
997
|
}
|
|
1034
|
-
async function
|
|
998
|
+
async function partiallySignTransaction(keyPairs, transaction) {
|
|
1035
999
|
const compiledMessage = compileMessage(transaction);
|
|
1036
1000
|
const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
|
|
1001
|
+
const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
|
|
1037
1002
|
const publicKeySignaturePairs = await Promise.all(
|
|
1038
1003
|
keyPairs.map(
|
|
1039
|
-
(keyPair) => Promise.all([
|
|
1040
|
-
addresses.getAddressFromPublicKey(keyPair.publicKey),
|
|
1041
|
-
getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
|
|
1042
|
-
])
|
|
1004
|
+
(keyPair) => Promise.all([addresses.getAddressFromPublicKey(keyPair.publicKey), keys.signBytes(keyPair.privateKey, wireMessageBytes)])
|
|
1043
1005
|
)
|
|
1044
1006
|
);
|
|
1045
1007
|
for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
|
|
@@ -1052,9 +1014,11 @@ async function signTransaction(keyPairs, transaction) {
|
|
|
1052
1014
|
Object.freeze(out);
|
|
1053
1015
|
return out;
|
|
1054
1016
|
}
|
|
1055
|
-
function
|
|
1056
|
-
|
|
1057
|
-
|
|
1017
|
+
async function signTransaction(keyPairs, transaction) {
|
|
1018
|
+
const out = await partiallySignTransaction(keyPairs, transaction);
|
|
1019
|
+
assertTransactionIsFullySigned(out);
|
|
1020
|
+
Object.freeze(out);
|
|
1021
|
+
return out;
|
|
1058
1022
|
}
|
|
1059
1023
|
function assertTransactionIsFullySigned(transaction) {
|
|
1060
1024
|
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
|
|
@@ -1065,19 +1029,14 @@ function assertTransactionIsFullySigned(transaction) {
|
|
|
1065
1029
|
}
|
|
1066
1030
|
});
|
|
1067
1031
|
}
|
|
1068
|
-
|
|
1069
|
-
// src/wire-transaction.ts
|
|
1070
1032
|
function getBase64EncodedWireTransaction(transaction) {
|
|
1071
1033
|
const wireTransactionBytes = getTransactionEncoder().encode(transaction);
|
|
1072
|
-
|
|
1073
|
-
return btoa(String.fromCharCode(...wireTransactionBytes));
|
|
1074
|
-
}
|
|
1034
|
+
return codecsStrings.getBase64Decoder().decode(wireTransactionBytes)[0];
|
|
1075
1035
|
}
|
|
1076
1036
|
|
|
1077
1037
|
exports.appendTransactionInstruction = appendTransactionInstruction;
|
|
1078
1038
|
exports.assertIsBlockhash = assertIsBlockhash;
|
|
1079
1039
|
exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
|
|
1080
|
-
exports.assertIsTransactionSignature = assertIsTransactionSignature;
|
|
1081
1040
|
exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
|
|
1082
1041
|
exports.createTransaction = createTransaction;
|
|
1083
1042
|
exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
|
|
@@ -1086,10 +1045,9 @@ exports.getTransactionCodec = getTransactionCodec;
|
|
|
1086
1045
|
exports.getTransactionDecoder = getTransactionDecoder;
|
|
1087
1046
|
exports.getTransactionEncoder = getTransactionEncoder;
|
|
1088
1047
|
exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
|
|
1089
|
-
exports.
|
|
1048
|
+
exports.partiallySignTransaction = partiallySignTransaction;
|
|
1090
1049
|
exports.prependTransactionInstruction = prependTransactionInstruction;
|
|
1091
1050
|
exports.setTransactionFeePayer = setTransactionFeePayer;
|
|
1092
1051
|
exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
|
|
1093
1052
|
exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
|
|
1094
1053
|
exports.signTransaction = signTransaction;
|
|
1095
|
-
exports.transactionSignature = transactionSignature;
|