@aptos-labs/ts-sdk 0.0.0

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.
Files changed (110) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +144 -0
  3. package/dist/browser/index.global.js +410 -0
  4. package/dist/browser/index.global.js.map +1 -0
  5. package/dist/cjs/index.d.ts +4965 -0
  6. package/dist/cjs/index.js +4762 -0
  7. package/dist/cjs/index.js.map +1 -0
  8. package/dist/esm/index.d.ts +4965 -0
  9. package/dist/esm/index.mjs +4645 -0
  10. package/dist/esm/index.mjs.map +1 -0
  11. package/dist/types/index.d.ts +1247 -0
  12. package/dist/types/index.js +151 -0
  13. package/dist/types/index.js.map +1 -0
  14. package/package.json +79 -0
  15. package/src/api/account.ts +360 -0
  16. package/src/api/aptos.ts +103 -0
  17. package/src/api/aptosConfig.ts +77 -0
  18. package/src/api/coin.ts +39 -0
  19. package/src/api/digitalAsset.ts +192 -0
  20. package/src/api/event.ts +78 -0
  21. package/src/api/faucet.ts +30 -0
  22. package/src/api/fungibleAsset.ts +82 -0
  23. package/src/api/general.ts +188 -0
  24. package/src/api/index.ts +5 -0
  25. package/src/api/staking.ts +58 -0
  26. package/src/api/transaction.ts +135 -0
  27. package/src/api/transactionSubmission.ts +168 -0
  28. package/src/bcs/consts.ts +12 -0
  29. package/src/bcs/deserializer.ts +248 -0
  30. package/src/bcs/index.ts +9 -0
  31. package/src/bcs/serializable/entryFunctionBytes.ts +61 -0
  32. package/src/bcs/serializable/fixedBytes.ts +65 -0
  33. package/src/bcs/serializable/movePrimitives.ts +211 -0
  34. package/src/bcs/serializable/moveStructs.ts +462 -0
  35. package/src/bcs/serializer.ts +353 -0
  36. package/src/client/core.ts +106 -0
  37. package/src/client/get.ts +109 -0
  38. package/src/client/index.ts +7 -0
  39. package/src/client/post.ts +90 -0
  40. package/src/client/types.ts +58 -0
  41. package/src/core/account.ts +180 -0
  42. package/src/core/accountAddress.ts +407 -0
  43. package/src/core/authenticationKey.ts +102 -0
  44. package/src/core/common.ts +40 -0
  45. package/src/core/crypto/asymmetricCrypto.ts +77 -0
  46. package/src/core/crypto/ed25519.ts +224 -0
  47. package/src/core/crypto/index.ts +7 -0
  48. package/src/core/crypto/multiEd25519.ts +251 -0
  49. package/src/core/crypto/secp256k1.ts +227 -0
  50. package/src/core/hex.ts +177 -0
  51. package/src/core/index.ts +9 -0
  52. package/src/index.ts +12 -0
  53. package/src/internal/account.ts +484 -0
  54. package/src/internal/coin.ts +32 -0
  55. package/src/internal/digitalAsset.ts +302 -0
  56. package/src/internal/event.ts +88 -0
  57. package/src/internal/faucet.ts +41 -0
  58. package/src/internal/fungibleAsset.ts +114 -0
  59. package/src/internal/general.ts +160 -0
  60. package/src/internal/queries/TokenActivitiesFieldsFragment.graphql +17 -0
  61. package/src/internal/queries/currentTokenOwnershipFieldsFragment.graphql +45 -0
  62. package/src/internal/queries/getAccountCoinCount.graphql +7 -0
  63. package/src/internal/queries/getAccountCoinsData.graphql +32 -0
  64. package/src/internal/queries/getAccountCollectionsWithOwnedTokens.graphql +33 -0
  65. package/src/internal/queries/getAccountOwnedObjects.graphql +16 -0
  66. package/src/internal/queries/getAccountOwnedTokens.graphql +11 -0
  67. package/src/internal/queries/getAccountOwnedTokensByTokenData.graphql +11 -0
  68. package/src/internal/queries/getAccountOwnedTokensFromCollectionAddress.graphql +11 -0
  69. package/src/internal/queries/getAccountTokensCount.graphql +7 -0
  70. package/src/internal/queries/getAccountTransactionsCount.graphql +7 -0
  71. package/src/internal/queries/getChainTopUserTransactions.graphql +5 -0
  72. package/src/internal/queries/getCollectionData.graphql +20 -0
  73. package/src/internal/queries/getCurrentFungibleAssetBalances.graphql +17 -0
  74. package/src/internal/queries/getDelegatedStakingActivities.graphql +12 -0
  75. package/src/internal/queries/getEvents.graphql +12 -0
  76. package/src/internal/queries/getFungibleAssetActivities.graphql +20 -0
  77. package/src/internal/queries/getFungibleAssetMetadata.graphql +16 -0
  78. package/src/internal/queries/getNumberOfDelegatorsQuery.graphql +9 -0
  79. package/src/internal/queries/getProcessorStatus.graphql +7 -0
  80. package/src/internal/queries/getTokenActivity.graphql +11 -0
  81. package/src/internal/queries/getTokenCurrentOwner.graphql +11 -0
  82. package/src/internal/queries/getTokenData.graphql +38 -0
  83. package/src/internal/staking.ts +68 -0
  84. package/src/internal/transaction.ts +245 -0
  85. package/src/internal/transactionSubmission.ts +162 -0
  86. package/src/transactions/authenticator/account.ts +121 -0
  87. package/src/transactions/authenticator/transaction.ts +222 -0
  88. package/src/transactions/instances/chainId.ts +26 -0
  89. package/src/transactions/instances/identifier.ts +28 -0
  90. package/src/transactions/instances/index.ts +9 -0
  91. package/src/transactions/instances/moduleId.ts +53 -0
  92. package/src/transactions/instances/rawTransaction.ts +199 -0
  93. package/src/transactions/instances/signedTransaction.ts +43 -0
  94. package/src/transactions/instances/transactionArgument.ts +37 -0
  95. package/src/transactions/instances/transactionPayload.ts +407 -0
  96. package/src/transactions/transaction_builder/transaction_builder.ts +541 -0
  97. package/src/transactions/typeTag/typeTag.ts +487 -0
  98. package/src/transactions/types.ts +262 -0
  99. package/src/types/codegen.yaml +33 -0
  100. package/src/types/generated/operations.ts +623 -0
  101. package/src/types/generated/queries.ts +737 -0
  102. package/src/types/generated/types.ts +10387 -0
  103. package/src/types/index.ts +944 -0
  104. package/src/types/indexer.ts +93 -0
  105. package/src/utils/apiEndpoints.ts +36 -0
  106. package/src/utils/const.ts +51 -0
  107. package/src/utils/hdKey.ts +113 -0
  108. package/src/utils/helpers.ts +12 -0
  109. package/src/utils/memoize.ts +68 -0
  110. package/src/version.ts +9 -0
@@ -0,0 +1,541 @@
1
+ // Copyright © Aptos Foundation
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * This file handles the transaction creation lifecycle.
6
+ * It holds different operations to generate a transaction payload, a raw transaction,
7
+ * and a signed transaction that can be simulated, signed and submitted to chain.
8
+ */
9
+ import { sha3_256 as sha3Hash } from "@noble/hashes/sha3";
10
+ import { AptosConfig } from "../../api/aptosConfig";
11
+ import { Deserializer } from "../../bcs/deserializer";
12
+ import { AccountAddress, Hex, PublicKey } from "../../core";
13
+ import { Account } from "../../core/account";
14
+ import { Ed25519PublicKey, Ed25519Signature } from "../../core/crypto/ed25519";
15
+ import { Secp256k1PublicKey, Secp256k1Signature } from "../../core/crypto/secp256k1";
16
+ import { getInfo } from "../../internal/account";
17
+ import { getLedgerInfo } from "../../internal/general";
18
+ import { getGasPriceEstimation } from "../../internal/transaction";
19
+ import { HexInput, SigningScheme } from "../../types";
20
+ import { NetworkToChainId } from "../../utils/apiEndpoints";
21
+ import {
22
+ DEFAULT_MAX_GAS_AMOUNT,
23
+ DEFAULT_TXN_EXP_SEC_FROM_NOW,
24
+ RAW_TRANSACTION_SALT,
25
+ RAW_TRANSACTION_WITH_DATA_SALT,
26
+ } from "../../utils/const";
27
+ import {
28
+ AccountAuthenticator,
29
+ AccountAuthenticatorEd25519,
30
+ AccountAuthenticatorSecp256k1,
31
+ } from "../authenticator/account";
32
+ import {
33
+ TransactionAuthenticatorEd25519,
34
+ TransactionAuthenticatorFeePayer,
35
+ TransactionAuthenticatorMultiAgent,
36
+ TransactionAuthenticatorSecp256k1,
37
+ } from "../authenticator/transaction";
38
+ import {
39
+ ChainId,
40
+ EntryFunction,
41
+ FeePayerRawTransaction,
42
+ MultiAgentRawTransaction,
43
+ MultiSig,
44
+ MultiSigTransactionPayload,
45
+ RawTransaction,
46
+ Script,
47
+ TransactionPayloadEntryFunction,
48
+ TransactionPayloadMultisig,
49
+ TransactionPayloadScript,
50
+ } from "../instances";
51
+ import { SignedTransaction } from "../instances/signedTransaction";
52
+ import {
53
+ GenerateTransactionOptions,
54
+ TransactionPayload,
55
+ AnyRawTransactionInstance,
56
+ GenerateTransactionPayloadData,
57
+ GenerateFeePayerRawTransactionArgs,
58
+ GenerateMultiAgentRawTransactionArgs,
59
+ GenerateRawTransactionArgs,
60
+ GenerateSingleSignerRawTransactionArgs,
61
+ SingleSignerTransaction,
62
+ AnyRawTransaction,
63
+ FeePayerTransaction,
64
+ MultiAgentTransaction,
65
+ EntryFunctionData,
66
+ MultiSigData,
67
+ ScriptData,
68
+ SimulateTransactionData,
69
+ } from "../types";
70
+
71
+ /**
72
+ * We are defining function signatures, each with its specific input and output.
73
+ * These are the possible function signature for our `generateTransactionPayload` function.
74
+ * When we call our `generateTransactionPayload` function with the relevant type properties,
75
+ * Typescript can infer the return type based on the appropriate function overload.
76
+ */
77
+ export function generateTransactionPayload(args: EntryFunctionData): TransactionPayloadEntryFunction;
78
+ export function generateTransactionPayload(args: ScriptData): TransactionPayloadScript;
79
+ export function generateTransactionPayload(args: MultiSigData): TransactionPayloadMultisig;
80
+ export function generateTransactionPayload(args: GenerateTransactionPayloadData): TransactionPayload;
81
+ /**
82
+ * Builds a transaction payload based on the data argument and returns
83
+ * a transaction payload - TransactionPayloadScript | TransactionPayloadMultisig | TransactionPayloadEntryFunction
84
+ *
85
+ * @param args.data GenerateTransactionPayloadData
86
+ *
87
+ * @return TransactionPayload
88
+ */
89
+ export function generateTransactionPayload(args: GenerateTransactionPayloadData): TransactionPayload {
90
+ // generate script payload
91
+ if ("bytecode" in args) {
92
+ return new TransactionPayloadScript(
93
+ new Script(Hex.fromHexInput(args.bytecode).toUint8Array(), args.typeArguments ?? [], args.arguments),
94
+ );
95
+ }
96
+
97
+ // generate multi sig payload
98
+ if ("multisigAddress" in args) {
99
+ const funcNameParts = args.function.split("::");
100
+ return new TransactionPayloadMultisig(
101
+ new MultiSig(
102
+ args.multisigAddress,
103
+ new MultiSigTransactionPayload(
104
+ EntryFunction.build(
105
+ `${funcNameParts[0]}::${funcNameParts[1]}`,
106
+ funcNameParts[2],
107
+ args.typeArguments ?? [],
108
+ args.arguments,
109
+ ),
110
+ ),
111
+ ),
112
+ );
113
+ }
114
+
115
+ // generate entry function payload
116
+ const funcNameParts = args.function.split("::");
117
+ return new TransactionPayloadEntryFunction(
118
+ EntryFunction.build(
119
+ `${funcNameParts[0]}::${funcNameParts[1]}`,
120
+ funcNameParts[2],
121
+ args.typeArguments ?? [],
122
+ args.arguments,
123
+ ),
124
+ );
125
+ }
126
+
127
+ /**
128
+ * Generates a raw transaction
129
+ *
130
+ * @param args.aptosConfig AptosConfig
131
+ * @param args.sender The transaction's sender account address as a hex input
132
+ * @param args.payload The transaction payload - can create by using generateTransactionPayload()
133
+ *
134
+ * @returns RawTransaction
135
+ */
136
+ export async function generateRawTransaction(args: {
137
+ aptosConfig: AptosConfig;
138
+ sender: HexInput;
139
+ payload: TransactionPayload;
140
+ options?: GenerateTransactionOptions;
141
+ }): Promise<RawTransaction> {
142
+ const { aptosConfig, sender, payload, options } = args;
143
+
144
+ const getSequenceNumber = options?.accountSequenceNumber
145
+ ? Promise.resolve({ sequence_number: options.accountSequenceNumber })
146
+ : getInfo({ aptosConfig, accountAddress: sender });
147
+
148
+ const getChainId = NetworkToChainId[aptosConfig.network]
149
+ ? Promise.resolve({ chain_id: NetworkToChainId[aptosConfig.network] })
150
+ : getLedgerInfo({ aptosConfig });
151
+
152
+ const getGasUnitPrice = options?.gasUnitPrice
153
+ ? Promise.resolve({ gas_estimate: options.gasUnitPrice })
154
+ : getGasPriceEstimation({ aptosConfig });
155
+
156
+ const [{ sequence_number: sequenceNumber }, { chain_id: chainId }, { gas_estimate: gasEstimate }] = await Promise.all(
157
+ [getSequenceNumber, getChainId, getGasUnitPrice],
158
+ );
159
+
160
+ const { maxGasAmount, gasUnitPrice, expireTimestamp } = {
161
+ maxGasAmount: BigInt(DEFAULT_MAX_GAS_AMOUNT),
162
+ gasUnitPrice: BigInt(gasEstimate),
163
+ expireTimestamp: BigInt(Math.floor(Date.now() / 1000) + DEFAULT_TXN_EXP_SEC_FROM_NOW),
164
+ ...options,
165
+ };
166
+
167
+ return new RawTransaction(
168
+ AccountAddress.fromHexInput(sender),
169
+ BigInt(sequenceNumber),
170
+ payload,
171
+ BigInt(maxGasAmount),
172
+ BigInt(gasUnitPrice),
173
+ BigInt(expireTimestamp),
174
+ new ChainId(chainId),
175
+ );
176
+ }
177
+
178
+ /**
179
+ * We are defining function signatures, each with its specific input and output.
180
+ * These are the possible function signature for our `generateTransaction` function.
181
+ * When we call our `generateTransaction` function with the relevant type properties,
182
+ * Typescript can infer the return type based on the appropriate function overload.
183
+ */
184
+ export async function buildTransaction(args: GenerateSingleSignerRawTransactionArgs): Promise<SingleSignerTransaction>;
185
+ export async function buildTransaction(args: GenerateFeePayerRawTransactionArgs): Promise<FeePayerTransaction>;
186
+ export async function buildTransaction(args: GenerateMultiAgentRawTransactionArgs): Promise<MultiAgentTransaction>;
187
+ export async function buildTransaction(args: GenerateRawTransactionArgs): Promise<AnyRawTransaction>;
188
+ /**
189
+ * Generates a transaction based on the provided arguments
190
+ *
191
+ * Note: we can start with one function to support all different payload/transaction types,
192
+ * and if to complex to use, we could have function for each type
193
+ *
194
+ * @param args.aptosConfig AptosConfig
195
+ * @param args.sender The transaction's sender account address as a hex input
196
+ * @param args.payload The transaction payload - can create by using generateTransactionPayload()
197
+ * @param args.options optional. Transaction options object
198
+ * @param args.secondarySignerAddresses optional. For when want to create a multi signers transaction
199
+ * @param args.feePayerAddress optional. For when want to create a fee payer (aka sponsored) transaction
200
+ *
201
+ * @return An Aptos raw transaction type (note that it holds the raw transaction as a bcs serialized data)
202
+ * ```
203
+ * {
204
+ * rawTransaction: Uint8Array,
205
+ * secondarySignerAddresses? : Array<AccountAddress>,
206
+ * feePayerAddress?: AccountAddress
207
+ * }
208
+ * ```
209
+ */
210
+ export async function buildTransaction(args: GenerateRawTransactionArgs): Promise<AnyRawTransaction> {
211
+ const { aptosConfig, sender, payload, options, secondarySignerAddresses, feePayerAddress } = args;
212
+ // generate raw transaction
213
+ const rawTxn = await generateRawTransaction({
214
+ aptosConfig,
215
+ sender,
216
+ payload,
217
+ options,
218
+ });
219
+
220
+ if (feePayerAddress) {
221
+ const signers: Array<AccountAddress> = secondarySignerAddresses
222
+ ? secondarySignerAddresses.map((signer) => AccountAddress.fromHexInput(signer))
223
+ : [];
224
+
225
+ return {
226
+ rawTransaction: rawTxn.bcsToBytes(),
227
+ secondarySignerAddresses: signers,
228
+ feePayerAddress: AccountAddress.fromHexInput(feePayerAddress),
229
+ };
230
+ }
231
+
232
+ if (secondarySignerAddresses) {
233
+ const signers: Array<AccountAddress> = secondarySignerAddresses.map((signer) =>
234
+ AccountAddress.fromHexInput(signer),
235
+ );
236
+
237
+ return {
238
+ rawTransaction: rawTxn.bcsToBytes(),
239
+ secondarySignerAddresses: signers,
240
+ };
241
+ }
242
+ // return the raw transaction
243
+ return { rawTransaction: rawTxn.bcsToBytes() };
244
+ }
245
+
246
+ /**
247
+ * Simulate a transaction before signing and submit to chain
248
+ *
249
+ * @param args.transaction A aptos transaction type to sign
250
+ * @param args.signerPublicKey The signer public key
251
+ * @param args.secondarySignersPublicKeys optional. The secondary signers public keys if multi signers transaction
252
+ * @param args.feePayerPublicKey optional. The fee payer public key is a fee payer (aka sponsored) transaction
253
+ * @param args.options optional. SimulateTransactionOptions
254
+ *
255
+ * @returns A signed serialized transaction that can be simulated
256
+ */
257
+ export function generateSignedTransactionForSimulation(args: SimulateTransactionData): Uint8Array {
258
+ const { signerPublicKey, transaction, secondarySignersPublicKeys, feePayerPublicKey } = args;
259
+
260
+ const deserializer = new Deserializer(transaction.rawTransaction);
261
+ const deserializedTransaction = RawTransaction.deserialize(deserializer);
262
+
263
+ const accountAuthenticator = getAuthenticatorForSimulation(signerPublicKey);
264
+ // fee payer transaction
265
+ if (transaction.feePayerAddress) {
266
+ const transactionToSign = new FeePayerRawTransaction(
267
+ deserializedTransaction,
268
+ transaction.secondarySignerAddresses ?? [],
269
+ transaction.feePayerAddress,
270
+ );
271
+
272
+ let secondaryAccountAuthenticators: Array<AccountAuthenticator> = [];
273
+ if (secondarySignersPublicKeys) {
274
+ secondaryAccountAuthenticators = secondarySignersPublicKeys.map((publicKey) =>
275
+ getAuthenticatorForSimulation(publicKey),
276
+ );
277
+ }
278
+
279
+ const feePayerAuthenticator = getAuthenticatorForSimulation(feePayerPublicKey!);
280
+
281
+ const transactionAuthenticator = new TransactionAuthenticatorFeePayer(
282
+ accountAuthenticator,
283
+ transaction.secondarySignerAddresses ?? [],
284
+ secondaryAccountAuthenticators,
285
+ {
286
+ address: transaction.feePayerAddress,
287
+ authenticator: feePayerAuthenticator,
288
+ },
289
+ );
290
+ return new SignedTransaction(transactionToSign.raw_txn, transactionAuthenticator).bcsToBytes();
291
+ }
292
+
293
+ // multi agent transaction
294
+ if (transaction.secondarySignerAddresses) {
295
+ const transactionToSign = new MultiAgentRawTransaction(
296
+ deserializedTransaction,
297
+ transaction.secondarySignerAddresses,
298
+ );
299
+
300
+ let secondaryAccountAuthenticators: Array<AccountAuthenticator> = [];
301
+
302
+ secondaryAccountAuthenticators = secondarySignersPublicKeys!.map((publicKey) =>
303
+ getAuthenticatorForSimulation(publicKey),
304
+ );
305
+
306
+ const transactionAuthenticator = new TransactionAuthenticatorMultiAgent(
307
+ accountAuthenticator,
308
+ transaction.secondarySignerAddresses,
309
+ secondaryAccountAuthenticators,
310
+ );
311
+
312
+ return new SignedTransaction(transactionToSign.raw_txn, transactionAuthenticator).bcsToBytes();
313
+ }
314
+
315
+ // raw transaction
316
+ let transactionAuthenticator;
317
+ if (accountAuthenticator instanceof AccountAuthenticatorEd25519) {
318
+ transactionAuthenticator = new TransactionAuthenticatorEd25519(
319
+ accountAuthenticator.public_key,
320
+ accountAuthenticator.signature,
321
+ );
322
+ } else if (accountAuthenticator instanceof AccountAuthenticatorSecp256k1) {
323
+ transactionAuthenticator = new TransactionAuthenticatorSecp256k1(
324
+ accountAuthenticator.public_key,
325
+ accountAuthenticator.signature,
326
+ );
327
+ } else {
328
+ throw new Error("Invalid public key");
329
+ }
330
+ return new SignedTransaction(deserializedTransaction, transactionAuthenticator).bcsToBytes();
331
+ }
332
+
333
+ export function getAuthenticatorForSimulation(publicKey: PublicKey) {
334
+ if (publicKey instanceof Ed25519PublicKey) {
335
+ return new AccountAuthenticatorEd25519(
336
+ new Ed25519PublicKey(publicKey.toUint8Array()),
337
+ new Ed25519Signature(new Uint8Array(64)),
338
+ );
339
+ }
340
+ return new AccountAuthenticatorSecp256k1(
341
+ new Secp256k1PublicKey(publicKey.toUint8Array()),
342
+ new Secp256k1Signature(new Uint8Array(64)),
343
+ );
344
+ }
345
+
346
+ /**
347
+ * Sign a transaction that can later be submitted to chain
348
+ *
349
+ * @param args.signer The signer account to sign the transaction
350
+ * @param args.transaction A aptos transaction type to sign
351
+ *
352
+ * @return The signer AccountAuthenticator
353
+ */
354
+ export function sign(args: { signer: Account; transaction: AnyRawTransaction }): AccountAuthenticator {
355
+ const { signer, transaction } = args;
356
+
357
+ const transactionToSign = deriveTransactionType(transaction);
358
+
359
+ // get the signing message
360
+ const message = getSigningMessage(transactionToSign);
361
+
362
+ // account.signMessage
363
+ const signerSignature = signer.sign(message);
364
+
365
+ // return account authentication
366
+ switch (signer.signingScheme) {
367
+ case SigningScheme.Ed25519:
368
+ return new AccountAuthenticatorEd25519(
369
+ new Ed25519PublicKey(signer.publicKey.toUint8Array()),
370
+ new Ed25519Signature(signerSignature.toUint8Array()),
371
+ );
372
+ case SigningScheme.Secp256k1Ecdsa:
373
+ return new AccountAuthenticatorSecp256k1(
374
+ new Secp256k1PublicKey(signer.publicKey.toUint8Array()),
375
+ new Secp256k1Signature(signerSignature.toUint8Array()),
376
+ );
377
+ // TODO support MultiEd25519
378
+ default:
379
+ throw new Error(`Cannot sign transaction, signing scheme ${signer.signingScheme} not supported`);
380
+ }
381
+ }
382
+
383
+ /**
384
+ * Prepare a transaction to be submitted to chain
385
+ *
386
+ * @param args.transaction A aptos transaction type
387
+ * @param args.senderAuthenticator The account authenticator of the transaction sender
388
+ * @param args.secondarySignerAuthenticators optional. For when the transaction is a multi signers transaction
389
+ *
390
+ * @returns A SignedTransaction
391
+ */
392
+ export function generateSignedTransaction(args: {
393
+ transaction: AnyRawTransaction;
394
+ senderAuthenticator: AccountAuthenticator;
395
+ secondarySignerAuthenticators?: {
396
+ feePayerAuthenticator?: AccountAuthenticator;
397
+ additionalSignersAuthenticators?: Array<AccountAuthenticator>;
398
+ };
399
+ }): Uint8Array {
400
+ const { transaction, senderAuthenticator, secondarySignerAuthenticators } = args;
401
+
402
+ const transactionToSubmit = deriveTransactionType(transaction);
403
+
404
+ if (secondarySignerAuthenticators) {
405
+ return generateMultiSignersSignedTransaction(
406
+ transactionToSubmit as MultiAgentRawTransaction | FeePayerRawTransaction,
407
+ senderAuthenticator,
408
+ secondarySignerAuthenticators,
409
+ );
410
+ }
411
+
412
+ // submit single signer transaction
413
+
414
+ // deserialize the senderAuthenticator
415
+ const deserializer = new Deserializer(senderAuthenticator.bcsToBytes());
416
+ const accountAuthenticator = AccountAuthenticator.deserialize(deserializer);
417
+ // check what instance is accountAuthenticator
418
+ if (accountAuthenticator instanceof AccountAuthenticatorEd25519) {
419
+ const transactionAuthenticator = new TransactionAuthenticatorEd25519(
420
+ accountAuthenticator.public_key,
421
+ accountAuthenticator.signature,
422
+ );
423
+ // return signed transaction
424
+ return new SignedTransaction(transactionToSubmit as RawTransaction, transactionAuthenticator).bcsToBytes();
425
+ }
426
+
427
+ if (accountAuthenticator instanceof AccountAuthenticatorSecp256k1) {
428
+ const transactionAuthenticator = new TransactionAuthenticatorSecp256k1(
429
+ accountAuthenticator.public_key,
430
+ accountAuthenticator.signature,
431
+ );
432
+ // return signed transaction
433
+ return new SignedTransaction(transactionToSubmit as RawTransaction, transactionAuthenticator).bcsToBytes();
434
+ }
435
+
436
+ throw new Error(
437
+ `Cannot generate a signed transaction, ${accountAuthenticator} is not a supported account authentication scheme`,
438
+ );
439
+ }
440
+
441
+ /**
442
+ * Derive the raw transaction type - FeePayerRawTransaction or MultiAgentRawTransaction or RawTransaction
443
+ *
444
+ * @param transaction A aptos transaction type
445
+ *
446
+ * @returns FeePayerRawTransaction | MultiAgentRawTransaction | RawTransaction
447
+ */
448
+ export function deriveTransactionType(transaction: AnyRawTransaction): AnyRawTransactionInstance {
449
+ const deserializer = new Deserializer(transaction.rawTransaction);
450
+ const deserializedTransaction = RawTransaction.deserialize(deserializer);
451
+
452
+ if (transaction.feePayerAddress) {
453
+ return new FeePayerRawTransaction(
454
+ deserializedTransaction,
455
+ transaction.secondarySignerAddresses ?? [],
456
+ transaction.feePayerAddress,
457
+ );
458
+ }
459
+ if (transaction.secondarySignerAddresses) {
460
+ return new MultiAgentRawTransaction(deserializedTransaction, transaction.secondarySignerAddresses);
461
+ }
462
+
463
+ return deserializedTransaction as RawTransaction;
464
+ }
465
+
466
+ /**
467
+ * Generate a multi signers signed transaction that can be submitted to chain
468
+ *
469
+ * @param transaction MultiAgentRawTransaction | FeePayerRawTransaction
470
+ * @param senderAuthenticator The account authenticator of the transaction sender
471
+ * @param secondarySignerAuthenticators The extra signers account Authenticators
472
+ *
473
+ * @returns A SignedTransaction
474
+ */
475
+ export function generateMultiSignersSignedTransaction(
476
+ transaction: MultiAgentRawTransaction | FeePayerRawTransaction,
477
+ senderAuthenticator: AccountAuthenticator,
478
+ secondarySignerAuthenticators: {
479
+ feePayerAuthenticator?: AccountAuthenticator;
480
+ additionalSignersAuthenticators?: Array<AccountAuthenticator>;
481
+ },
482
+ ) {
483
+ if (transaction instanceof FeePayerRawTransaction) {
484
+ if (!secondarySignerAuthenticators.feePayerAuthenticator) {
485
+ throw new Error("Must provide a feePayerAuthenticator argument to generate a signed fee payer transaction");
486
+ }
487
+ const { feePayerAuthenticator, additionalSignersAuthenticators } = secondarySignerAuthenticators;
488
+ const txAuthenticatorFeePayer = new TransactionAuthenticatorFeePayer(
489
+ senderAuthenticator,
490
+ transaction.secondary_signer_addresses,
491
+ additionalSignersAuthenticators ?? [],
492
+ {
493
+ address: transaction.fee_payer_address,
494
+ authenticator: feePayerAuthenticator,
495
+ },
496
+ );
497
+ return new SignedTransaction(transaction.raw_txn, txAuthenticatorFeePayer).bcsToBytes();
498
+ }
499
+ if (transaction instanceof MultiAgentRawTransaction) {
500
+ if (!secondarySignerAuthenticators.additionalSignersAuthenticators) {
501
+ throw new Error(
502
+ "Must provide a additionalSignersAuthenticators argument to generate a signed multi agent transaction",
503
+ );
504
+ }
505
+ const { additionalSignersAuthenticators } = secondarySignerAuthenticators;
506
+ const multiAgentAuthenticator = new TransactionAuthenticatorMultiAgent(
507
+ senderAuthenticator,
508
+ transaction.secondary_signer_addresses,
509
+ additionalSignersAuthenticators ?? [],
510
+ );
511
+ return new SignedTransaction(transaction.raw_txn, multiAgentAuthenticator).bcsToBytes();
512
+ }
513
+
514
+ throw new Error(
515
+ `Cannot prepare multi signers transaction to submission, ${typeof transaction} transaction is not supported`,
516
+ );
517
+ }
518
+
519
+ export function getSigningMessage(rawTxn: AnyRawTransactionInstance): Uint8Array {
520
+ const hash = sha3Hash.create();
521
+
522
+ if (rawTxn instanceof RawTransaction) {
523
+ hash.update(RAW_TRANSACTION_SALT);
524
+ } else if (rawTxn instanceof MultiAgentRawTransaction) {
525
+ hash.update(RAW_TRANSACTION_WITH_DATA_SALT);
526
+ } else if (rawTxn instanceof FeePayerRawTransaction) {
527
+ hash.update(RAW_TRANSACTION_WITH_DATA_SALT);
528
+ } else {
529
+ throw new Error(`Unknown transaction type to sign on: ${rawTxn}`);
530
+ }
531
+
532
+ const prefix = hash.digest();
533
+
534
+ const body = rawTxn.bcsToBytes();
535
+
536
+ const mergedArray = new Uint8Array(prefix.length + body.length);
537
+ mergedArray.set(prefix);
538
+ mergedArray.set(body, prefix.length);
539
+
540
+ return mergedArray;
541
+ }