@aptos-labs/ts-sdk 0.0.2 → 0.0.4

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 (67) hide show
  1. package/README.md +33 -24
  2. package/dist/browser/index.global.js +26 -25
  3. package/dist/browser/index.global.js.map +1 -1
  4. package/dist/cjs/index.d.ts +1036 -342
  5. package/dist/cjs/index.js +1585 -676
  6. package/dist/cjs/index.js.map +1 -1
  7. package/dist/esm/index.d.ts +1036 -342
  8. package/dist/esm/index.mjs +1507 -671
  9. package/dist/esm/index.mjs.map +1 -1
  10. package/dist/types/index.d.ts +29 -34
  11. package/dist/types/index.js +4 -2
  12. package/dist/types/index.js.map +1 -1
  13. package/package.json +3 -2
  14. package/src/api/account.ts +19 -20
  15. package/src/api/ans.ts +58 -0
  16. package/src/api/aptos.ts +7 -1
  17. package/src/api/coin.ts +7 -7
  18. package/src/api/digitalAsset.ts +14 -13
  19. package/src/api/event.ts +5 -4
  20. package/src/api/faucet.ts +8 -3
  21. package/src/api/general.ts +2 -2
  22. package/src/api/staking.ts +5 -4
  23. package/src/api/transactionSubmission.ts +51 -42
  24. package/src/bcs/deserializer.ts +4 -4
  25. package/src/bcs/serializable/fixedBytes.ts +1 -1
  26. package/src/bcs/serializable/moveStructs.ts +21 -45
  27. package/src/bcs/serializer.ts +4 -4
  28. package/src/client/core.ts +14 -6
  29. package/src/core/account.ts +92 -34
  30. package/src/core/accountAddress.ts +37 -31
  31. package/src/core/authenticationKey.ts +35 -11
  32. package/src/core/crypto/anyPublicKey.ts +14 -18
  33. package/src/core/crypto/ed25519.ts +54 -1
  34. package/src/core/crypto/hdKey.ts +105 -0
  35. package/src/core/crypto/index.ts +2 -0
  36. package/src/core/crypto/multiKey.ts +122 -0
  37. package/src/core/crypto/secp256k1.ts +38 -0
  38. package/src/index.ts +1 -3
  39. package/src/internal/account.ts +84 -62
  40. package/src/internal/ans.ts +177 -0
  41. package/src/internal/coin.ts +12 -12
  42. package/src/internal/digitalAsset.ts +23 -24
  43. package/src/internal/event.ts +8 -8
  44. package/src/internal/faucet.ts +12 -8
  45. package/src/internal/general.ts +3 -3
  46. package/src/internal/staking.ts +8 -8
  47. package/src/internal/transactionSubmission.ts +111 -33
  48. package/src/transactions/authenticator/account.ts +39 -0
  49. package/src/transactions/authenticator/index.ts +5 -0
  50. package/src/transactions/authenticator/transaction.ts +6 -6
  51. package/src/transactions/index.ts +9 -0
  52. package/src/transactions/instances/index.ts +2 -0
  53. package/src/transactions/instances/moduleId.ts +1 -1
  54. package/src/transactions/instances/rotationProofChallenge.ts +58 -0
  55. package/src/transactions/instances/transactionPayload.ts +13 -8
  56. package/src/transactions/transactionBuilder/helpers.ts +103 -0
  57. package/src/transactions/transactionBuilder/index.ts +6 -0
  58. package/src/transactions/transactionBuilder/remoteAbi.ts +339 -0
  59. package/src/transactions/{transaction_builder/transaction_builder.ts → transactionBuilder/transactionBuilder.ts} +175 -108
  60. package/src/transactions/typeTag/index.ts +385 -0
  61. package/src/transactions/typeTag/parser.ts +22 -9
  62. package/src/transactions/types.ts +114 -62
  63. package/src/types/index.ts +28 -31
  64. package/src/utils/apiEndpoints.ts +8 -0
  65. package/src/version.ts +1 -1
  66. package/src/transactions/typeTag/typeTag.ts +0 -487
  67. package/src/utils/hdKey.ts +0 -113
@@ -10,10 +10,9 @@
10
10
 
11
11
  import { AptosConfig } from "../api/aptosConfig";
12
12
  import { AptosApiError, getAptosFullNode, paginateWithCursor } from "../client";
13
- import { AccountAddress } from "../core/accountAddress";
13
+ import { AccountAddress, AccountAddressInput } from "../core/accountAddress";
14
14
  import { Account } from "../core/account";
15
15
  import { PrivateKey } from "../core/crypto/asymmetricCrypto";
16
- import { Hex } from "../core/hex";
17
16
  import { getTableItem, queryIndexer } from "./general";
18
17
  import {
19
18
  AccountData,
@@ -22,11 +21,10 @@ import {
22
21
  GetAccountOwnedObjectsResponse,
23
22
  GetAccountOwnedTokensFromCollectionResponse,
24
23
  GetAccountOwnedTokensQueryResponse,
25
- HexInput,
26
24
  LedgerVersion,
27
25
  MoveModuleBytecode,
28
26
  MoveResource,
29
- MoveResourceType,
27
+ MoveStructType,
30
28
  OrderBy,
31
29
  PaginationArgs,
32
30
  SigningScheme,
@@ -57,26 +55,29 @@ import { memoizeAsync } from "../utils/memoize";
57
55
  import { Secp256k1PrivateKey, AuthenticationKey, Ed25519PrivateKey } from "../core";
58
56
  import { AnyPublicKey } from "../core/crypto/anyPublicKey";
59
57
 
60
- export async function getInfo(args: { aptosConfig: AptosConfig; accountAddress: HexInput }): Promise<AccountData> {
58
+ export async function getInfo(args: {
59
+ aptosConfig: AptosConfig;
60
+ accountAddress: AccountAddressInput;
61
+ }): Promise<AccountData> {
61
62
  const { aptosConfig, accountAddress } = args;
62
63
  const { data } = await getAptosFullNode<{}, AccountData>({
63
64
  aptosConfig,
64
65
  originMethod: "getInfo",
65
- path: `accounts/${AccountAddress.fromHexInput(accountAddress).toString()}`,
66
+ path: `accounts/${AccountAddress.from(accountAddress).toString()}`,
66
67
  });
67
68
  return data;
68
69
  }
69
70
 
70
71
  export async function getModules(args: {
71
72
  aptosConfig: AptosConfig;
72
- accountAddress: HexInput;
73
+ accountAddress: AccountAddressInput;
73
74
  options?: PaginationArgs & LedgerVersion;
74
75
  }): Promise<MoveModuleBytecode[]> {
75
76
  const { aptosConfig, accountAddress, options } = args;
76
77
  return paginateWithCursor<{}, MoveModuleBytecode[]>({
77
78
  aptosConfig,
78
79
  originMethod: "getModules",
79
- path: `accounts/${AccountAddress.fromHexInput(accountAddress).toString()}/modules`,
80
+ path: `accounts/${AccountAddress.from(accountAddress).toString()}/modules`,
80
81
  params: {
81
82
  ledger_version: options?.ledgerVersion,
82
83
  start: options?.offset,
@@ -95,7 +96,7 @@ export async function getModules(args: {
95
96
  */
96
97
  export async function getModule(args: {
97
98
  aptosConfig: AptosConfig;
98
- accountAddress: HexInput;
99
+ accountAddress: AccountAddressInput;
99
100
  moduleName: string;
100
101
  options?: LedgerVersion;
101
102
  }): Promise<MoveModuleBytecode> {
@@ -114,7 +115,7 @@ export async function getModule(args: {
114
115
 
115
116
  async function getModuleInner(args: {
116
117
  aptosConfig: AptosConfig;
117
- accountAddress: HexInput;
118
+ accountAddress: AccountAddressInput;
118
119
  moduleName: string;
119
120
  options?: LedgerVersion;
120
121
  }): Promise<MoveModuleBytecode> {
@@ -123,7 +124,7 @@ async function getModuleInner(args: {
123
124
  const { data } = await getAptosFullNode<{}, MoveModuleBytecode>({
124
125
  aptosConfig,
125
126
  originMethod: "getModule",
126
- path: `accounts/${AccountAddress.fromHexInput(accountAddress).toString()}/module/${moduleName}`,
127
+ path: `accounts/${AccountAddress.from(accountAddress).toString()}/module/${moduleName}`,
127
128
  params: { ledger_version: options?.ledgerVersion },
128
129
  });
129
130
  return data;
@@ -131,28 +132,28 @@ async function getModuleInner(args: {
131
132
 
132
133
  export async function getTransactions(args: {
133
134
  aptosConfig: AptosConfig;
134
- accountAddress: HexInput;
135
+ accountAddress: AccountAddressInput;
135
136
  options?: PaginationArgs;
136
137
  }): Promise<TransactionResponse[]> {
137
138
  const { aptosConfig, accountAddress, options } = args;
138
139
  return paginateWithCursor<{}, TransactionResponse[]>({
139
140
  aptosConfig,
140
141
  originMethod: "getTransactions",
141
- path: `accounts/${AccountAddress.fromHexInput(accountAddress).toString()}/transactions`,
142
+ path: `accounts/${AccountAddress.from(accountAddress).toString()}/transactions`,
142
143
  params: { start: options?.offset, limit: options?.limit },
143
144
  });
144
145
  }
145
146
 
146
147
  export async function getResources(args: {
147
148
  aptosConfig: AptosConfig;
148
- accountAddress: HexInput;
149
+ accountAddress: AccountAddressInput;
149
150
  options?: PaginationArgs & LedgerVersion;
150
151
  }): Promise<MoveResource[]> {
151
152
  const { aptosConfig, accountAddress, options } = args;
152
153
  return paginateWithCursor<{}, MoveResource[]>({
153
154
  aptosConfig,
154
155
  originMethod: "getResources",
155
- path: `accounts/${AccountAddress.fromHexInput(accountAddress).toString()}/resources`,
156
+ path: `accounts/${AccountAddress.from(accountAddress).toString()}/resources`,
156
157
  params: {
157
158
  ledger_version: options?.ledgerVersion,
158
159
  start: options?.offset,
@@ -163,15 +164,15 @@ export async function getResources(args: {
163
164
 
164
165
  export async function getResource<T extends {}>(args: {
165
166
  aptosConfig: AptosConfig;
166
- accountAddress: HexInput;
167
- resourceType: MoveResourceType;
167
+ accountAddress: AccountAddressInput;
168
+ resourceType: MoveStructType;
168
169
  options?: LedgerVersion;
169
170
  }): Promise<T> {
170
171
  const { aptosConfig, accountAddress, resourceType, options } = args;
171
172
  const { data } = await getAptosFullNode<{}, MoveResource>({
172
173
  aptosConfig,
173
174
  originMethod: "getResource",
174
- path: `accounts/${AccountAddress.fromHexInput(accountAddress).toString()}/resource/${resourceType}`,
175
+ path: `accounts/${AccountAddress.from(accountAddress).toString()}/resource/${resourceType}`,
175
176
  params: { ledger_version: options?.ledgerVersion },
176
177
  });
177
178
  return data.data as T;
@@ -179,7 +180,7 @@ export async function getResource<T extends {}>(args: {
179
180
 
180
181
  export async function lookupOriginalAccountAddress(args: {
181
182
  aptosConfig: AptosConfig;
182
- authenticationKey: HexInput;
183
+ authenticationKey: AccountAddressInput;
183
184
  options?: LedgerVersion;
184
185
  }): Promise<AccountAddress> {
185
186
  const { aptosConfig, authenticationKey, options } = args;
@@ -197,24 +198,26 @@ export async function lookupOriginalAccountAddress(args: {
197
198
  address_map: { handle },
198
199
  } = resource;
199
200
 
201
+ const authKeyAddress = AccountAddress.from(authenticationKey);
202
+
200
203
  // If the address is not found in the address map, which means its not rotated
201
204
  // then return the address as is
202
205
  try {
203
- const originalAddress = await getTableItem({
206
+ const originalAddress = await getTableItem<string>({
204
207
  aptosConfig,
205
208
  handle,
206
209
  data: {
207
- key: Hex.fromHexInput(authenticationKey).toString(),
210
+ key: authKeyAddress.toString(),
208
211
  key_type: "address",
209
212
  value_type: "address",
210
213
  },
211
214
  options,
212
215
  });
213
216
 
214
- return AccountAddress.fromHexInput(originalAddress);
217
+ return AccountAddress.from(originalAddress);
215
218
  } catch (err) {
216
219
  if (err instanceof AptosApiError && err.data.error_code === "table_item_not_found") {
217
- return AccountAddress.fromHexInput(authenticationKey);
220
+ return authKeyAddress;
218
221
  }
219
222
 
220
223
  throw err;
@@ -223,15 +226,15 @@ export async function lookupOriginalAccountAddress(args: {
223
226
 
224
227
  export async function getAccountTokensCount(args: {
225
228
  aptosConfig: AptosConfig;
226
- accountAddress: HexInput;
229
+ accountAddress: AccountAddressInput;
227
230
  }): Promise<number> {
228
231
  const { aptosConfig, accountAddress } = args;
229
232
 
230
- const address = AccountAddress.fromHexInput(accountAddress).toString();
233
+ const address = AccountAddress.from(accountAddress).toStringLong();
231
234
 
232
- const whereCondition: any = {
235
+ const whereCondition: { owner_address: { _eq: string }; amount: { _gt: number } } = {
233
236
  owner_address: { _eq: address },
234
- amount: { _gt: "0" },
237
+ amount: { _gt: 0 },
235
238
  };
236
239
 
237
240
  const graphqlQuery = {
@@ -252,7 +255,7 @@ export async function getAccountTokensCount(args: {
252
255
 
253
256
  export async function getAccountOwnedTokens(args: {
254
257
  aptosConfig: AptosConfig;
255
- accountAddress: HexInput;
258
+ accountAddress: AccountAddressInput;
256
259
  options?: {
257
260
  tokenStandard?: TokenStandard;
258
261
  pagination?: PaginationArgs;
@@ -260,12 +263,13 @@ export async function getAccountOwnedTokens(args: {
260
263
  };
261
264
  }): Promise<GetAccountOwnedTokensQueryResponse> {
262
265
  const { aptosConfig, accountAddress, options } = args;
263
- const address = AccountAddress.fromHexInput(accountAddress).toString();
266
+ const address = AccountAddress.from(accountAddress).toStringLong();
264
267
 
265
- const whereCondition: any = {
266
- owner_address: { _eq: address },
267
- amount: { _gt: 0 },
268
- };
268
+ const whereCondition: { owner_address: { _eq: string }; amount: { _gt: number }; token_standard?: { _eq: string } } =
269
+ {
270
+ owner_address: { _eq: address },
271
+ amount: { _gt: 0 },
272
+ };
269
273
 
270
274
  if (options?.tokenStandard) {
271
275
  whereCondition.token_standard = { _eq: options?.tokenStandard };
@@ -292,8 +296,8 @@ export async function getAccountOwnedTokens(args: {
292
296
 
293
297
  export async function getAccountOwnedTokensFromCollectionAddress(args: {
294
298
  aptosConfig: AptosConfig;
295
- accountAddress: HexInput;
296
- collectionAddress: HexInput;
299
+ accountAddress: AccountAddressInput;
300
+ collectionAddress: AccountAddressInput;
297
301
  options?: {
298
302
  tokenStandard?: TokenStandard;
299
303
  pagination?: PaginationArgs;
@@ -301,10 +305,15 @@ export async function getAccountOwnedTokensFromCollectionAddress(args: {
301
305
  };
302
306
  }): Promise<GetAccountOwnedTokensFromCollectionResponse> {
303
307
  const { aptosConfig, accountAddress, collectionAddress, options } = args;
304
- const ownerAddress = AccountAddress.fromHexInput(accountAddress).toString();
305
- const collAddress = Hex.fromHexInput(collectionAddress).toString();
306
-
307
- const whereCondition: any = {
308
+ const ownerAddress = AccountAddress.from(accountAddress).toStringLong();
309
+ const collAddress = AccountAddress.from(collectionAddress).toStringLong();
310
+
311
+ const whereCondition: {
312
+ owner_address: { _eq: string };
313
+ current_token_data: { collection_id: { _eq: string } };
314
+ amount: { _gt: number };
315
+ token_standard?: { _eq: string };
316
+ } = {
308
317
  owner_address: { _eq: ownerAddress },
309
318
  current_token_data: { collection_id: { _eq: collAddress } },
310
319
  amount: { _gt: 0 },
@@ -335,7 +344,7 @@ export async function getAccountOwnedTokensFromCollectionAddress(args: {
335
344
 
336
345
  export async function getAccountCollectionsWithOwnedTokens(args: {
337
346
  aptosConfig: AptosConfig;
338
- accountAddress: HexInput;
347
+ accountAddress: AccountAddressInput;
339
348
  options?: {
340
349
  tokenStandard?: TokenStandard;
341
350
  pagination?: PaginationArgs;
@@ -343,9 +352,13 @@ export async function getAccountCollectionsWithOwnedTokens(args: {
343
352
  };
344
353
  }): Promise<GetAccountCollectionsWithOwnedTokenResponse> {
345
354
  const { aptosConfig, accountAddress, options } = args;
346
- const address = AccountAddress.fromHexInput(accountAddress).toString();
355
+ const address = AccountAddress.from(accountAddress).toStringLong();
347
356
 
348
- const whereCondition: any = {
357
+ const whereCondition: {
358
+ owner_address: { _eq: string };
359
+ amount: { _gt: number };
360
+ current_collection?: { token_standard: { _eq: string } };
361
+ } = {
349
362
  owner_address: { _eq: address },
350
363
  amount: { _gt: 0 },
351
364
  };
@@ -377,11 +390,11 @@ export async function getAccountCollectionsWithOwnedTokens(args: {
377
390
 
378
391
  export async function getAccountTransactionsCount(args: {
379
392
  aptosConfig: AptosConfig;
380
- accountAddress: HexInput;
393
+ accountAddress: AccountAddressInput;
381
394
  }): Promise<number> {
382
395
  const { aptosConfig, accountAddress } = args;
383
396
 
384
- const address = AccountAddress.fromHexInput(accountAddress).toString();
397
+ const address = AccountAddress.from(accountAddress).toStringLong();
385
398
 
386
399
  const graphqlQuery = {
387
400
  query: GetAccountTransactionsCount,
@@ -403,16 +416,16 @@ export async function getAccountTransactionsCount(args: {
403
416
 
404
417
  export async function getAccountCoinsData(args: {
405
418
  aptosConfig: AptosConfig;
406
- accountAddress: HexInput;
419
+ accountAddress: AccountAddressInput;
407
420
  options?: {
408
421
  pagination?: PaginationArgs;
409
422
  orderBy?: OrderBy<GetAccountCoinsDataResponse[0]>;
410
423
  };
411
424
  }): Promise<GetAccountCoinsDataResponse> {
412
425
  const { aptosConfig, accountAddress, options } = args;
413
- const address = AccountAddress.fromHexInput(accountAddress).toString();
426
+ const address = AccountAddress.from(accountAddress).toStringLong();
414
427
 
415
- const whereCondition: any = {
428
+ const whereCondition: { owner_address: { _eq: string } } = {
416
429
  owner_address: { _eq: address },
417
430
  };
418
431
 
@@ -437,10 +450,10 @@ export async function getAccountCoinsData(args: {
437
450
 
438
451
  export async function getAccountCoinsCount(args: {
439
452
  aptosConfig: AptosConfig;
440
- accountAddress: HexInput;
453
+ accountAddress: AccountAddressInput;
441
454
  }): Promise<number> {
442
455
  const { aptosConfig, accountAddress } = args;
443
- const address = AccountAddress.fromHexInput(accountAddress).toString();
456
+ const address = AccountAddress.from(accountAddress).toStringLong();
444
457
 
445
458
  const graphqlQuery = {
446
459
  query: GetAccountCoinsCount,
@@ -462,16 +475,16 @@ export async function getAccountCoinsCount(args: {
462
475
 
463
476
  export async function getAccountOwnedObjects(args: {
464
477
  aptosConfig: AptosConfig;
465
- accountAddress: HexInput;
478
+ accountAddress: AccountAddressInput;
466
479
  options?: {
467
480
  pagination?: PaginationArgs;
468
481
  orderBy?: OrderBy<GetAccountOwnedObjectsResponse[0]>;
469
482
  };
470
483
  }): Promise<GetAccountOwnedObjectsResponse> {
471
484
  const { aptosConfig, accountAddress, options } = args;
472
- const address = AccountAddress.fromHexInput(accountAddress).toString();
485
+ const address = AccountAddress.from(accountAddress).toStringLong();
473
486
 
474
- const whereCondition: any = {
487
+ const whereCondition: { owner_address: { _eq: string } } = {
475
488
  owner_address: { _eq: address },
476
489
  };
477
490
  const graphqlQuery = {
@@ -492,6 +505,15 @@ export async function getAccountOwnedObjects(args: {
492
505
  return data.current_objects;
493
506
  }
494
507
 
508
+ /**
509
+ * NOTE: There is a potential issue once unified single signer scheme will be adopted
510
+ * by the community.
511
+ *
512
+ * Becuase on could create 2 accounts with the same private key with this new authenticator type,
513
+ * we’ll need to determine the order in which we lookup the accounts. First unified
514
+ * scheme and then legacy scheme vs first legacy scheme and then unified scheme.
515
+ *
516
+ */
495
517
  export async function deriveAccountFromPrivateKey(args: {
496
518
  aptosConfig: AptosConfig;
497
519
  privateKey: PrivateKey;
@@ -502,30 +524,30 @@ export async function deriveAccountFromPrivateKey(args: {
502
524
  if (privateKey instanceof Secp256k1PrivateKey) {
503
525
  // private key is secp256k1, therefore we know it for sure uses a single signer key
504
526
  const authKey = AuthenticationKey.fromPublicKeyAndScheme({ publicKey, scheme: SigningScheme.SingleKey });
505
- const address = new AccountAddress({ data: authKey.toUint8Array() });
506
- return Account.fromPrivateKey({ privateKey, address });
527
+ const address = authKey.derivedAddress();
528
+ return Account.fromPrivateKeyAndAddress({ privateKey, address });
507
529
  }
508
530
 
509
531
  if (privateKey instanceof Ed25519PrivateKey) {
510
532
  // lookup single sender ed25519
511
- const SingleSenderTransactionAuthenticatorAuthKey = AuthenticationKey.fromPublicKeyAndScheme({
533
+ const singleSenderTransactionAuthenticatorAuthKey = AuthenticationKey.fromPublicKeyAndScheme({
512
534
  publicKey,
513
535
  scheme: SigningScheme.SingleKey,
514
536
  });
515
537
  const isSingleSenderTransactionAuthenticator = await isAccountExist({
516
- authKey: SingleSenderTransactionAuthenticatorAuthKey,
538
+ authKey: singleSenderTransactionAuthenticatorAuthKey,
517
539
  aptosConfig,
518
540
  });
519
541
  if (isSingleSenderTransactionAuthenticator) {
520
- const address = new AccountAddress({ data: SingleSenderTransactionAuthenticatorAuthKey.toUint8Array() });
521
- return Account.fromPrivateKey({ privateKey, address });
542
+ const address = singleSenderTransactionAuthenticatorAuthKey.derivedAddress();
543
+ return Account.fromPrivateKeyAndAddress({ privateKey, address, legacy: false });
522
544
  }
523
545
  // lookup legacy ed25519
524
546
  const legacyAuthKey = AuthenticationKey.fromPublicKeyAndScheme({ publicKey, scheme: SigningScheme.Ed25519 });
525
547
  const isLegacyEd25519 = await isAccountExist({ authKey: legacyAuthKey, aptosConfig });
526
548
  if (isLegacyEd25519) {
527
- const address = new AccountAddress({ data: legacyAuthKey.toUint8Array() });
528
- return Account.fromPrivateKey({ privateKey, address, legacy: true });
549
+ const address = legacyAuthKey.derivedAddress();
550
+ return Account.fromPrivateKeyAndAddress({ privateKey, address, legacy: true });
529
551
  }
530
552
  }
531
553
  // if we are here, it means we couldn't find an address with an
@@ -537,13 +559,13 @@ export async function isAccountExist(args: { aptosConfig: AptosConfig; authKey:
537
559
  const { aptosConfig, authKey } = args;
538
560
  const accountAddress = await lookupOriginalAccountAddress({
539
561
  aptosConfig,
540
- authenticationKey: authKey.toString(),
562
+ authenticationKey: authKey.derivedAddress(),
541
563
  });
542
564
 
543
565
  try {
544
566
  await getInfo({
545
567
  aptosConfig,
546
- accountAddress: accountAddress.toString(),
568
+ accountAddress,
547
569
  });
548
570
  return true;
549
571
  } catch (error: any) {
@@ -0,0 +1,177 @@
1
+ // Copyright © Aptos Foundation
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * This file contains the underlying implementations for exposed API surface in
6
+ * the {@link api/name}. By moving the methods out into a separate file,
7
+ * other namespaces and processes can access these methods without depending on the entire
8
+ * name namespace and without having a dependency cycle error.
9
+ */
10
+
11
+ import { AptosConfig } from "../api/aptosConfig";
12
+ import { MoveOption, MoveString, U64 } from "../bcs";
13
+ import { Account, AccountAddress } from "../core";
14
+ import { InputGenerateTransactionOptions, InputSingleSignerTransaction } from "../transactions/types";
15
+ import { HexInput, MoveAddressType, MoveValue } from "../types";
16
+ import { Network } from "../utils/apiEndpoints";
17
+ import { view } from "./general";
18
+ import { generateTransaction } from "./transactionSubmission";
19
+
20
+ export const VALIDATION_RULES_DESCRIPTION = [
21
+ "A name must be between 3 and 63 characters long,",
22
+ "and can only contain lowercase a-z, 0-9, and hyphens.",
23
+ "A name may not start or end with a hyphen.",
24
+ ].join(" ");
25
+
26
+ /**
27
+ *
28
+ * @param fragment A fragment of a name, either the domain or subdomain
29
+ * @returns boolean indicating if the fragment is a valid fragment
30
+ */
31
+ export function isValidANSSegment(fragment: string): boolean {
32
+ if (!fragment) return false;
33
+ if (fragment.length < 3) return false;
34
+ if (fragment.length > 63) return false;
35
+ // only lowercase a-z and 0-9 are allowed, along with -. a domain may not start or end with a hyphen
36
+ if (!/^[a-z\d][a-z\d-]{1,61}[a-z\d]$/.test(fragment)) return false;
37
+ return true;
38
+ }
39
+
40
+ /**
41
+ * Checks if an ANS name is valid or not
42
+ *
43
+ * @param name A string of the domain name, can include or exclude the .apt suffix
44
+ */
45
+ export function isValidANSName(name: string): { domainName: string; subdomainName?: string } {
46
+ const [first, second, ...rest] = name.replace(/\.apt$/, "").split(".");
47
+
48
+ if (rest.length > 0) {
49
+ throw new Error(`${name} is invalid. A name can only have two parts, a domain and a subdomain separated by a "."`);
50
+ }
51
+
52
+ if (!isValidANSSegment(first)) {
53
+ throw new Error(`${first} is not valid. ${VALIDATION_RULES_DESCRIPTION}`);
54
+ }
55
+
56
+ if (second && !isValidANSSegment(second)) {
57
+ throw new Error(`${second} is not valid. ${VALIDATION_RULES_DESCRIPTION}`);
58
+ }
59
+
60
+ return {
61
+ domainName: second || first,
62
+ subdomainName: second ? first : undefined,
63
+ };
64
+ }
65
+
66
+ export const LOCAL_ANS_ACCOUNT_PK =
67
+ (process.env.ANS_TEST_ACCOUNT_PRIVATE_KEY as string) ||
68
+ "0x37368b46ce665362562c6d1d4ec01a08c8644c488690df5a17e13ba163e20221";
69
+ export const LOCAL_ANS_ACCOUNT_ADDRESS =
70
+ (process.env.ANS_TEST_ACCOUNT_ADDRESS as string) ||
71
+ "0x585fc9f0f0c54183b039ffc770ca282ebd87307916c215a3e692f2f8e4305e82";
72
+
73
+ const NetworkToAnsContract: Record<Network, string | null> = {
74
+ [Network.TESTNET]: "0x5f8fd2347449685cf41d4db97926ec3a096eaf381332be4f1318ad4d16a8497c",
75
+ [Network.MAINNET]: "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c",
76
+ [Network.LOCAL]: LOCAL_ANS_ACCOUNT_ADDRESS,
77
+ [Network.CUSTOM]: null,
78
+ [Network.DEVNET]: null,
79
+ };
80
+
81
+ function getRouterAddress(aptosConfig: AptosConfig): string {
82
+ const address = NetworkToAnsContract[aptosConfig.network];
83
+ if (!address) throw new Error(`The ANS contract is not deployed to ${aptosConfig.network}`);
84
+ return address;
85
+ }
86
+
87
+ const Some = <T>(value: T): MoveValue => ({ vec: [value] } as any);
88
+ const None = (): MoveValue => ({ vec: [] } as any);
89
+ // != here is intentional, we want to check for null and undefined
90
+ // eslint-disable-next-line eqeqeq
91
+ const Option = <T>(value: T | undefined | null): MoveValue => (value != undefined ? Some(value) : None());
92
+
93
+ const unwrapOption = <T>(option: any): T | undefined => {
94
+ if (!!option && typeof option === "object" && "vec" in option && Array.isArray(option.vec)) {
95
+ return option.vec[0];
96
+ }
97
+
98
+ return undefined;
99
+ };
100
+
101
+ export async function getOwnerAddress(args: { aptosConfig: AptosConfig; name: string }): Promise<string | undefined> {
102
+ const { aptosConfig, name } = args;
103
+ const routerAddress = getRouterAddress(aptosConfig);
104
+ const { domainName, subdomainName } = isValidANSName(name);
105
+
106
+ const res = await view({
107
+ aptosConfig,
108
+ payload: {
109
+ function: `${routerAddress}::router::get_owner_addr`,
110
+ functionArguments: [domainName, Option(subdomainName)],
111
+ },
112
+ });
113
+
114
+ const owner = unwrapOption<MoveAddressType>(res[0]);
115
+
116
+ return owner ? AccountAddress.fromRelaxed(owner).toString() : undefined;
117
+ }
118
+
119
+ export interface RegisterNameParameters {
120
+ aptosConfig: AptosConfig;
121
+ sender: Account;
122
+ name: string;
123
+ expiration:
124
+ | { policy: "domain"; years: 1 }
125
+ | { policy: "subdomain:follow-domain" }
126
+ | { policy: "subdomain:independent"; expirationDate: Date };
127
+ transferable?: boolean;
128
+ toAddress?: HexInput;
129
+ targetAddress?: HexInput;
130
+ options?: InputGenerateTransactionOptions;
131
+ }
132
+
133
+ export async function registerName(args: RegisterNameParameters): Promise<InputSingleSignerTransaction> {
134
+ const { aptosConfig, expiration, name, sender, targetAddress, toAddress, options } = args;
135
+ const routerAddress = getRouterAddress(aptosConfig);
136
+ const { domainName, subdomainName } = isValidANSName(name);
137
+
138
+ const hasSubdomainPolicy =
139
+ expiration.policy === "subdomain:independent" || expiration.policy === "subdomain:follow-domain";
140
+
141
+ if (subdomainName && !hasSubdomainPolicy) {
142
+ throw new Error(
143
+ "Subdomains must have an expiration policy of either 'subdomain:independent' or 'subdomain:follow-domain'",
144
+ );
145
+ }
146
+
147
+ if (hasSubdomainPolicy && !subdomainName) {
148
+ throw new Error(`Policy is set to ${expiration.policy} but no subdomain was provided`);
149
+ }
150
+
151
+ if (expiration.policy === "domain") {
152
+ if (expiration.years !== 1) {
153
+ throw new Error("For now, names can only be registered for 1 year at a time");
154
+ }
155
+
156
+ const registrationDuration = expiration.years * 31536000;
157
+
158
+ const transaction = await generateTransaction({
159
+ aptosConfig,
160
+ sender: sender.accountAddress.toString(),
161
+ data: {
162
+ function: `${routerAddress}::router::register_domain`,
163
+ functionArguments: [
164
+ new MoveString(domainName),
165
+ new U64(registrationDuration),
166
+ new MoveOption(targetAddress ? AccountAddress.from(targetAddress) : null),
167
+ new MoveOption(toAddress ? AccountAddress.from(toAddress) : null),
168
+ ],
169
+ },
170
+ options,
171
+ });
172
+
173
+ return transaction as InputSingleSignerTransaction;
174
+ }
175
+
176
+ throw new Error(`Policy ${expiration.policy} is not supported yet`);
177
+ }
@@ -1,32 +1,32 @@
1
1
  import { AptosConfig } from "../api/aptosConfig";
2
2
  import { U64 } from "../bcs/serializable/movePrimitives";
3
- import { Account, AccountAddress } from "../core";
4
- import { GenerateTransactionOptions, SingleSignerTransaction } from "../transactions/types";
5
- import { StructTag, TypeTagStruct } from "../transactions/typeTag/typeTag";
6
- import { HexInput, AnyNumber, MoveResourceType } from "../types";
3
+ import { Account, AccountAddress, AccountAddressInput } from "../core";
4
+ import { InputGenerateTransactionOptions, InputSingleSignerTransaction } from "../transactions/types";
5
+ import { AnyNumber, MoveStructType } from "../types";
7
6
  import { APTOS_COIN } from "../utils/const";
8
7
  import { generateTransaction } from "./transactionSubmission";
8
+ import { parseTypeTag } from "../transactions/typeTag/parser";
9
9
 
10
10
  export async function transferCoinTransaction(args: {
11
11
  aptosConfig: AptosConfig;
12
12
  sender: Account;
13
- recipient: HexInput;
13
+ recipient: AccountAddressInput;
14
14
  amount: AnyNumber;
15
- coinType?: MoveResourceType;
16
- options?: GenerateTransactionOptions;
17
- }): Promise<SingleSignerTransaction> {
15
+ coinType?: MoveStructType;
16
+ options?: InputGenerateTransactionOptions;
17
+ }): Promise<InputSingleSignerTransaction> {
18
18
  const { aptosConfig, sender, recipient, amount, coinType, options } = args;
19
19
  const coinStructType = coinType ?? APTOS_COIN;
20
20
  const transaction = await generateTransaction({
21
21
  aptosConfig,
22
- sender: sender.accountAddress.toString(),
22
+ sender: sender.accountAddress,
23
23
  data: {
24
24
  function: "0x1::aptos_account::transfer_coins",
25
- typeArguments: [new TypeTagStruct(StructTag.fromString(coinStructType))],
26
- functionArguments: [AccountAddress.fromHexInput(recipient), new U64(amount)],
25
+ typeArguments: [parseTypeTag(coinStructType)],
26
+ functionArguments: [AccountAddress.from(recipient), new U64(amount)],
27
27
  },
28
28
  options,
29
29
  });
30
30
 
31
- return transaction as SingleSignerTransaction;
31
+ return transaction as InputSingleSignerTransaction;
32
32
  }