@ar.io/sdk 3.11.0-alpha.7 → 3.11.0-alpha.9

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 (40) hide show
  1. package/README.md +52 -0
  2. package/bundles/web.bundle.min.js +119 -116
  3. package/lib/cjs/cli/cli.js +137 -122
  4. package/lib/cjs/cli/commands/readCommands.js +6 -0
  5. package/lib/cjs/common/ant.js +5 -5
  6. package/lib/cjs/common/io.js +37 -0
  7. package/lib/cjs/common/wayfinder/gateways/trusted-gateways.js +106 -0
  8. package/lib/cjs/common/wayfinder/index.js +6 -0
  9. package/lib/cjs/common/wayfinder/verification/data-root-verifier.js +139 -0
  10. package/lib/cjs/common/wayfinder/verification/hash-verifier.js +50 -0
  11. package/lib/cjs/common/wayfinder/wayfinder.js +407 -18
  12. package/lib/cjs/common/wayfinder/wayfinder.test.js +262 -3
  13. package/lib/cjs/types/wayfinder.js +1 -0
  14. package/lib/cjs/utils/hash.js +56 -0
  15. package/lib/cjs/version.js +1 -1
  16. package/lib/esm/cli/cli.js +138 -123
  17. package/lib/esm/cli/commands/readCommands.js +5 -0
  18. package/lib/esm/common/ant.js +5 -5
  19. package/lib/esm/common/io.js +37 -0
  20. package/lib/esm/common/wayfinder/gateways/trusted-gateways.js +102 -0
  21. package/lib/esm/common/wayfinder/index.js +6 -0
  22. package/lib/esm/common/wayfinder/verification/data-root-verifier.js +130 -0
  23. package/lib/esm/common/wayfinder/verification/hash-verifier.js +46 -0
  24. package/lib/esm/common/wayfinder/wayfinder.js +401 -18
  25. package/lib/esm/common/wayfinder/wayfinder.test.js +263 -4
  26. package/lib/esm/types/wayfinder.js +1 -0
  27. package/lib/esm/utils/hash.js +50 -0
  28. package/lib/esm/version.js +1 -1
  29. package/lib/types/cli/commands/readCommands.d.ts +1 -0
  30. package/lib/types/common/io.d.ts +5 -2
  31. package/lib/types/common/wayfinder/gateways/trusted-gateways.d.ts +51 -0
  32. package/lib/types/common/wayfinder/index.d.ts +3 -0
  33. package/lib/types/common/wayfinder/verification/data-root-verifier.d.ts +31 -0
  34. package/lib/types/common/wayfinder/verification/hash-verifier.d.ts +27 -0
  35. package/lib/types/common/wayfinder/wayfinder.d.ts +148 -10
  36. package/lib/types/types/io.d.ts +16 -1
  37. package/lib/types/types/wayfinder.d.ts +43 -0
  38. package/lib/types/utils/hash.d.ts +4 -0
  39. package/lib/types/version.d.ts +1 -1
  40. package/package.json +1 -1
@@ -33,6 +33,7 @@ const utils_js_1 = require("./utils.js");
33
33
  .version(version_js_1.version)
34
34
  .description('AR.IO Network CLI')
35
35
  .helpCommand(true), options_js_1.globalOptions);
36
+ // # Getters
36
37
  (0, utils_js_1.makeCommand)({
37
38
  name: 'info',
38
39
  description: 'Get network info',
@@ -43,6 +44,18 @@ const utils_js_1 = require("./utils.js");
43
44
  description: 'Get the total token supply',
44
45
  action: (options) => (0, utils_js_1.readARIOFromOptions)(options).getTokenSupply(),
45
46
  });
47
+ (0, utils_js_1.makeCommand)({
48
+ name: 'balance',
49
+ description: 'Get the balance of an address',
50
+ options: [options_js_1.optionMap.address],
51
+ action: (options) => (0, utils_js_1.readARIOFromOptions)(options)
52
+ .getBalance({ address: (0, utils_js_1.requiredAddressFromOptions)(options) })
53
+ .then((result) => ({
54
+ address: (0, utils_js_1.requiredAddressFromOptions)(options),
55
+ mARIOBalance: result,
56
+ message: `Provided address current has a balance of ${(0, utils_js_1.formatARIOWithCommas)(new token_js_1.mARIOToken(result).toARIO())} ARIO`,
57
+ })),
58
+ });
46
59
  (0, utils_js_1.makeCommand)({
47
60
  name: 'get-registration-fees',
48
61
  description: 'Get registration fees',
@@ -69,24 +82,18 @@ const utils_js_1 = require("./utils.js");
69
82
  options: [options_js_1.optionMap.address],
70
83
  action: readCommands_js_1.getGateway,
71
84
  });
72
- (0, utils_js_1.makeCommand)({
73
- name: 'list-gateways',
74
- description: 'List the gateways of the network',
75
- options: options_js_1.paginationOptions,
76
- action: readCommands_js_1.listGateways,
77
- });
78
- (0, utils_js_1.makeCommand)({
79
- name: 'list-all-delegates',
80
- description: 'List all paginated delegates from all gateways',
81
- options: options_js_1.paginationOptions,
82
- action: readCommands_js_1.listAllDelegatesCLICommand,
83
- });
84
85
  (0, utils_js_1.makeCommand)({
85
86
  name: 'get-gateway-delegates',
86
87
  description: 'Get the delegates of a gateway',
87
88
  options: options_js_1.paginationAddressOptions,
88
89
  action: readCommands_js_1.getGatewayDelegates,
89
90
  });
91
+ (0, utils_js_1.makeCommand)({
92
+ name: 'get-gateway-vaults',
93
+ description: 'Get the vaults of a gateway',
94
+ options: options_js_1.paginationAddressOptions,
95
+ action: readCommands_js_1.getGatewayVaults,
96
+ });
90
97
  (0, utils_js_1.makeCommand)({
91
98
  name: 'get-delegations',
92
99
  description: 'Get all stake delegated to gateways from this address',
@@ -105,36 +112,18 @@ const utils_js_1 = require("./utils.js");
105
112
  options: [options_js_1.optionMap.name],
106
113
  action: readCommands_js_1.getArNSRecord,
107
114
  });
108
- (0, utils_js_1.makeCommand)({
109
- name: 'list-arns-records',
110
- description: 'List all ArNS records',
111
- options: options_js_1.paginationOptions,
112
- action: readCommands_js_1.listArNSRecords,
113
- });
114
115
  (0, utils_js_1.makeCommand)({
115
116
  name: 'get-arns-reserved-name',
116
117
  description: 'Get a reserved ArNS name',
117
118
  options: [options_js_1.optionMap.name],
118
119
  action: readCommands_js_1.getArNSReservedName,
119
120
  });
120
- (0, utils_js_1.makeCommand)({
121
- name: 'list-arns-reserved-names',
122
- description: 'Get all reserved ArNS names',
123
- options: options_js_1.paginationOptions,
124
- action: readCommands_js_1.listArNSReservedNames,
125
- });
126
121
  (0, utils_js_1.makeCommand)({
127
122
  name: 'get-arns-returned-name',
128
123
  description: 'Get an ArNS returned name by name',
129
124
  options: [options_js_1.optionMap.name],
130
125
  action: readCommands_js_1.getArNSReturnedName,
131
126
  });
132
- (0, utils_js_1.makeCommand)({
133
- name: 'list-arns-returned-names',
134
- description: 'Get all ArNS recently returned names',
135
- options: options_js_1.paginationOptions,
136
- action: readCommands_js_1.listArNSReturnedNames,
137
- });
138
127
  (0, utils_js_1.makeCommand)({
139
128
  name: 'get-epoch',
140
129
  description: 'Get epoch data',
@@ -195,14 +184,11 @@ const utils_js_1 = require("./utils.js");
195
184
  action: readCommands_js_1.getCostDetails,
196
185
  });
197
186
  (0, utils_js_1.makeCommand)({
198
- name: 'list-vaults',
199
- description: 'Get all wallet vaults',
200
- options: options_js_1.paginationOptions,
201
- action: (o) => (0, utils_js_1.readARIOFromOptions)(o)
202
- .getVaults((0, utils_js_1.paginationParamsFromOptions)(o))
203
- .then((result) => result.items.length ? result : { message: 'No vaults found' }),
187
+ name: 'get-primary-name',
188
+ description: 'Get primary name',
189
+ options: [options_js_1.optionMap.address, options_js_1.optionMap.name],
190
+ action: readCommands_js_1.getPrimaryName,
204
191
  });
205
- // TODO: Could assert valid arweave (or ETH) addresses at CLI level when coming from options (no need from wallet)
206
192
  (0, utils_js_1.makeCommand)({
207
193
  name: 'get-primary-name-request',
208
194
  description: 'Get primary name request',
@@ -215,6 +201,66 @@ const utils_js_1 = require("./utils.js");
215
201
  message: `No primary name request found`,
216
202
  }),
217
203
  });
204
+ (0, utils_js_1.makeCommand)({
205
+ name: 'get-redelegation-fee',
206
+ description: 'Get redelegation fee',
207
+ options: [options_js_1.optionMap.address],
208
+ action: (options) => (0, utils_js_1.readARIOFromOptions)(options).getRedelegationFee({
209
+ address: (0, utils_js_1.requiredAddressFromOptions)(options),
210
+ }),
211
+ });
212
+ (0, utils_js_1.makeCommand)({
213
+ name: 'get-vault',
214
+ description: 'Get the vault of provided address and vault ID',
215
+ options: options_js_1.getVaultOptions,
216
+ action: readCommands_js_1.getVault,
217
+ });
218
+ // # ArNS Resolution
219
+ (0, utils_js_1.makeCommand)({
220
+ name: 'resolve-arns-name',
221
+ description: 'Resolve an ArNS name',
222
+ options: [options_js_1.optionMap.name],
223
+ action: readCommands_js_1.resolveArNSName,
224
+ });
225
+ // # Paginated handlers
226
+ (0, utils_js_1.makeCommand)({
227
+ name: 'list-gateways',
228
+ description: 'List the gateways of the network',
229
+ options: options_js_1.paginationOptions,
230
+ action: readCommands_js_1.listGateways,
231
+ });
232
+ (0, utils_js_1.makeCommand)({
233
+ name: 'list-all-delegates',
234
+ description: 'List all paginated delegates from all gateways',
235
+ options: options_js_1.paginationOptions,
236
+ action: readCommands_js_1.listAllDelegatesCLICommand,
237
+ });
238
+ (0, utils_js_1.makeCommand)({
239
+ name: 'list-arns-records',
240
+ description: 'List all ArNS records',
241
+ options: options_js_1.paginationOptions,
242
+ action: readCommands_js_1.listArNSRecords,
243
+ });
244
+ (0, utils_js_1.makeCommand)({
245
+ name: 'list-arns-reserved-names',
246
+ description: 'Get all reserved ArNS names',
247
+ options: options_js_1.paginationOptions,
248
+ action: readCommands_js_1.listArNSReservedNames,
249
+ });
250
+ (0, utils_js_1.makeCommand)({
251
+ name: 'list-arns-returned-names',
252
+ description: 'Get all ArNS recently returned names',
253
+ options: options_js_1.paginationOptions,
254
+ action: readCommands_js_1.listArNSReturnedNames,
255
+ });
256
+ (0, utils_js_1.makeCommand)({
257
+ name: 'list-vaults',
258
+ description: 'Get all wallet vaults',
259
+ options: options_js_1.paginationOptions,
260
+ action: (o) => (0, utils_js_1.readARIOFromOptions)(o)
261
+ .getVaults((0, utils_js_1.paginationParamsFromOptions)(o))
262
+ .then((result) => result.items.length ? result : { message: 'No vaults found' }),
263
+ });
218
264
  (0, utils_js_1.makeCommand)({
219
265
  name: 'list-primary-name-requests',
220
266
  description: 'Get primary name requests',
@@ -223,12 +269,6 @@ const utils_js_1 = require("./utils.js");
223
269
  .getPrimaryNameRequests((0, utils_js_1.paginationParamsFromOptions)(o))
224
270
  .then((result) => result.items.length ? result : { message: 'No requests found' }),
225
271
  });
226
- (0, utils_js_1.makeCommand)({
227
- name: 'get-primary-name',
228
- description: 'Get primary name',
229
- options: [options_js_1.optionMap.address, options_js_1.optionMap.name],
230
- action: readCommands_js_1.getPrimaryName,
231
- });
232
272
  (0, utils_js_1.makeCommand)({
233
273
  name: 'list-primary-names',
234
274
  description: 'Get primary names',
@@ -237,18 +277,6 @@ const utils_js_1 = require("./utils.js");
237
277
  .getPrimaryNames((0, utils_js_1.paginationParamsFromOptions)(o))
238
278
  .then((result) => result.items.length ? result : { message: 'No names found' }),
239
279
  });
240
- (0, utils_js_1.makeCommand)({
241
- name: 'balance',
242
- description: 'Get the balance of an address',
243
- options: [options_js_1.optionMap.address],
244
- action: (options) => (0, utils_js_1.readARIOFromOptions)(options)
245
- .getBalance({ address: (0, utils_js_1.requiredAddressFromOptions)(options) })
246
- .then((result) => ({
247
- address: (0, utils_js_1.requiredAddressFromOptions)(options),
248
- mARIOBalance: result,
249
- message: `Provided address current has a balance of ${(0, utils_js_1.formatARIOWithCommas)(new token_js_1.mARIOToken(result).toARIO())} ARIO`,
250
- })),
251
- });
252
280
  (0, utils_js_1.makeCommand)({
253
281
  name: 'list-balances',
254
282
  description: 'List all balances',
@@ -257,32 +285,13 @@ const utils_js_1 = require("./utils.js");
257
285
  .getBalances((0, utils_js_1.paginationParamsFromOptions)(o))
258
286
  .then((result) => result.items.length ? result : { message: 'No balances found' }),
259
287
  });
260
- (0, utils_js_1.makeCommand)({
261
- name: 'get-redelegation-fee',
262
- description: 'Get redelegation fee',
263
- options: [options_js_1.optionMap.address],
264
- action: (options) => (0, utils_js_1.readARIOFromOptions)(options).getRedelegationFee({
265
- address: (0, utils_js_1.requiredAddressFromOptions)(options),
266
- }),
267
- });
268
- (0, utils_js_1.makeCommand)({
269
- name: 'get-vault',
270
- description: 'Get the vault of provided address and vault ID',
271
- options: options_js_1.getVaultOptions,
272
- action: readCommands_js_1.getVault,
273
- });
274
- (0, utils_js_1.makeCommand)({
275
- name: 'get-gateway-vaults',
276
- description: 'Get the vaults of a gateway',
277
- options: options_js_1.paginationAddressOptions,
278
- action: readCommands_js_1.getGatewayVaults,
279
- });
280
288
  (0, utils_js_1.makeCommand)({
281
289
  name: 'list-all-gateway-vaults',
282
290
  description: 'List vaults from all gateways',
283
291
  options: options_js_1.paginationAddressOptions,
284
292
  action: readCommands_js_1.getAllGatewayVaults,
285
293
  });
294
+ // # Actions
286
295
  (0, utils_js_1.makeCommand)({
287
296
  name: 'transfer',
288
297
  description: 'Transfer ARIO to another address',
@@ -418,24 +427,8 @@ const utils_js_1 = require("./utils.js");
418
427
  options: options_js_1.arnsPurchaseOptions,
419
428
  action: arnsPurchaseCommands_js_1.requestPrimaryNameCLICommand,
420
429
  });
421
- (0, utils_js_1.makeCommand)({
422
- name: 'spawn-ant',
423
- description: 'Spawn an ANT process',
424
- options: options_js_1.antStateOptions,
425
- action: async (options) => {
426
- const state = (0, utils_js_1.getANTStateFromOptions)(options);
427
- const antProcessId = await (0, index_js_1.spawnANT)({
428
- state,
429
- signer: (0, utils_js_1.requiredAoSignerFromOptions)(options),
430
- logger: (0, utils_js_1.getLoggerFromOptions)(options),
431
- });
432
- return {
433
- processId: antProcessId,
434
- state,
435
- message: `Spawned ANT process with process ID ${antProcessId}`,
436
- };
437
- },
438
- });
430
+ // # ANTS
431
+ // # Getters
439
432
  (0, utils_js_1.makeCommand)({
440
433
  name: 'get-ant-state',
441
434
  description: 'Get the state of an ANT process',
@@ -462,14 +455,6 @@ const utils_js_1 = require("./utils.js");
462
455
  })) ?? { message: 'No record found' });
463
456
  },
464
457
  });
465
- (0, utils_js_1.makeCommand)({
466
- name: 'list-ant-records',
467
- description: 'Get the records of an ANT process',
468
- options: [options_js_1.optionMap.processId],
469
- action: async (options) => {
470
- return (0, utils_js_1.readANTFromOptions)(options).getRecords();
471
- },
472
- });
473
458
  (0, utils_js_1.makeCommand)({
474
459
  name: 'get-ant-owner',
475
460
  description: 'Get the owner of an ANT process',
@@ -478,14 +463,6 @@ const utils_js_1 = require("./utils.js");
478
463
  return (0, utils_js_1.readANTFromOptions)(options).getOwner();
479
464
  },
480
465
  });
481
- (0, utils_js_1.makeCommand)({
482
- name: 'list-ant-controllers',
483
- description: 'List the controllers of an ANT process',
484
- options: [options_js_1.optionMap.processId],
485
- action: async (options) => {
486
- return (0, utils_js_1.readANTFromOptions)(options).getControllers();
487
- },
488
- });
489
466
  (0, utils_js_1.makeCommand)({
490
467
  name: 'get-ant-name',
491
468
  description: 'Get the name of an ANT process',
@@ -512,6 +489,42 @@ const utils_js_1 = require("./utils.js");
512
489
  });
513
490
  },
514
491
  });
492
+ // # Spawn
493
+ (0, utils_js_1.makeCommand)({
494
+ name: 'spawn-ant',
495
+ description: 'Spawn an ANT process',
496
+ options: options_js_1.antStateOptions,
497
+ action: async (options) => {
498
+ const state = (0, utils_js_1.getANTStateFromOptions)(options);
499
+ const antProcessId = await (0, index_js_1.spawnANT)({
500
+ state,
501
+ signer: (0, utils_js_1.requiredAoSignerFromOptions)(options),
502
+ logger: (0, utils_js_1.getLoggerFromOptions)(options),
503
+ });
504
+ return {
505
+ processId: antProcessId,
506
+ state,
507
+ message: `Spawned ANT process with process ID ${antProcessId}`,
508
+ };
509
+ },
510
+ });
511
+ // # ANT Paginated Handlers
512
+ (0, utils_js_1.makeCommand)({
513
+ name: 'list-ant-records',
514
+ description: 'Get the records of an ANT process',
515
+ options: [options_js_1.optionMap.processId],
516
+ action: async (options) => {
517
+ return (0, utils_js_1.readANTFromOptions)(options).getRecords();
518
+ },
519
+ });
520
+ (0, utils_js_1.makeCommand)({
521
+ name: 'list-ant-controllers',
522
+ description: 'List the controllers of an ANT process',
523
+ options: [options_js_1.optionMap.processId],
524
+ action: async (options) => {
525
+ return (0, utils_js_1.readANTFromOptions)(options).getControllers();
526
+ },
527
+ });
515
528
  (0, utils_js_1.makeCommand)({
516
529
  name: 'list-ant-balances',
517
530
  description: 'Get the balances of an ANT process',
@@ -520,6 +533,7 @@ const utils_js_1 = require("./utils.js");
520
533
  return (0, utils_js_1.readANTFromOptions)(options).getBalances();
521
534
  },
522
535
  });
536
+ // # Actions
523
537
  (0, utils_js_1.makeCommand)({
524
538
  name: 'transfer-ant-ownership',
525
539
  description: 'Transfer ownership of an ANT process',
@@ -554,6 +568,18 @@ const utils_js_1 = require("./utils.js");
554
568
  }, (0, utils_js_1.customTagsFromOptions)(options));
555
569
  },
556
570
  });
571
+ (0, utils_js_1.makeCommand)({
572
+ name: 'remove-ant-record',
573
+ description: 'Remove a record from an ANT process',
574
+ options: [options_js_1.optionMap.processId, options_js_1.optionMap.undername, ...options_js_1.writeActionOptions],
575
+ action: async (options) => {
576
+ const undername = (0, utils_js_1.requiredStringFromOptions)(options, 'undername');
577
+ await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to remove the record with undername ${undername}?`, options);
578
+ return (0, utils_js_1.writeANTFromOptions)(options).removeRecord({
579
+ undername,
580
+ }, (0, utils_js_1.customTagsFromOptions)(options));
581
+ },
582
+ });
557
583
  (0, utils_js_1.makeCommand)({
558
584
  name: 'set-ant-record',
559
585
  description: 'Set a record of an ANT process. Deprecated: use set-ant-base-name and set-ant-undername',
@@ -572,18 +598,6 @@ const utils_js_1 = require("./utils.js");
572
598
  options: options_js_1.setAntUndernameOptions,
573
599
  action: antCommands_js_1.setAntRecordCLICommand,
574
600
  });
575
- (0, utils_js_1.makeCommand)({
576
- name: 'remove-ant-record',
577
- description: 'Remove a record from an ANT process',
578
- options: [options_js_1.optionMap.processId, options_js_1.optionMap.undername, ...options_js_1.writeActionOptions],
579
- action: async (options) => {
580
- const undername = (0, utils_js_1.requiredStringFromOptions)(options, 'undername');
581
- await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to remove the record with undername ${undername}?`, options);
582
- return (0, utils_js_1.writeANTFromOptions)(options).removeRecord({
583
- undername,
584
- }, (0, utils_js_1.customTagsFromOptions)(options));
585
- },
586
- });
587
601
  (0, utils_js_1.makeCommand)({
588
602
  name: 'set-ant-ticker',
589
603
  description: 'Set the ticker of an ANT process',
@@ -644,11 +658,11 @@ const utils_js_1 = require("./utils.js");
644
658
  const txId = (0, utils_js_1.requiredStringFromOptions)(options, 'transactionId');
645
659
  await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to set the ANT logo to target Arweave TxID ${txId}?`, options);
646
660
  return (0, utils_js_1.writeANTFromOptions)(options).setLogo({
647
- // TODO: Could take a logo file, upload it to Arweave, get transaction ID
648
661
  txId,
649
662
  }, (0, utils_js_1.customTagsFromOptions)(options));
650
663
  },
651
664
  });
665
+ // # ARIO Actions
652
666
  (0, utils_js_1.makeCommand)({
653
667
  name: 'release-name',
654
668
  description: 'Release the name of an ANT process',
@@ -715,6 +729,7 @@ const utils_js_1 = require("./utils.js");
715
729
  }, (0, utils_js_1.customTagsFromOptions)(options));
716
730
  },
717
731
  });
732
+ // # Utilities
718
733
  (0, utils_js_1.makeCommand)({
719
734
  name: 'write-action',
720
735
  description: 'Send a write action to an AO Process',
@@ -21,6 +21,7 @@ exports.getPrimaryName = getPrimaryName;
21
21
  exports.getGatewayVaults = getGatewayVaults;
22
22
  exports.getAllGatewayVaults = getAllGatewayVaults;
23
23
  exports.getVault = getVault;
24
+ exports.resolveArNSName = resolveArNSName;
24
25
  const token_js_1 = require("../../types/token.js");
25
26
  const utils_js_1 = require("../utils.js");
26
27
  async function getGateway(o) {
@@ -188,3 +189,8 @@ async function getVault(o) {
188
189
  message: `No vault found for provided address and vault ID`,
189
190
  });
190
191
  }
192
+ async function resolveArNSName(o) {
193
+ const name = (0, utils_js_1.requiredStringFromOptions)(o, 'name');
194
+ const result = await (0, utils_js_1.readARIOFromOptions)(o).resolveArNSName({ name });
195
+ return result ?? { message: `No record found for name ${name}` };
196
+ }
@@ -93,12 +93,12 @@ class AoANTReadable {
93
93
  * ```
94
94
  */
95
95
  async getRecord({ undername }, { strict } = { strict: this.strict }) {
96
- const tags = [
97
- { name: 'Sub-Domain', value: undername },
98
- { name: 'Action', value: 'Record' },
99
- ];
96
+ // TODO: use sortedANTRecords to get priority on all records, even if ANT does not have a priority set
100
97
  const record = await this.process.read({
101
- tags,
98
+ tags: [
99
+ { name: 'Action', value: 'Record' },
100
+ { name: 'Sub-Domain', value: undername },
101
+ ],
102
102
  });
103
103
  if (strict)
104
104
  (0, schema_js_1.parseSchemaResult)(ant_js_1.AntRecordSchema.passthrough(), record);
@@ -21,6 +21,7 @@ const constants_js_1 = require("../constants.js");
21
21
  const index_js_1 = require("../types/index.js");
22
22
  const ao_js_1 = require("../utils/ao.js");
23
23
  const arweave_js_1 = require("../utils/arweave.js");
24
+ const ant_js_1 = require("./ant.js");
24
25
  const arweave_js_2 = require("./arweave.js");
25
26
  const ao_process_js_1 = require("./contracts/ao-process.js");
26
27
  const error_js_1 = require("./error.js");
@@ -624,6 +625,42 @@ class ARIOReadable {
624
625
  ],
625
626
  });
626
627
  }
628
+ async resolveArNSName({ name, }) {
629
+ const baseName = name.split('_').pop();
630
+ if (baseName === undefined) {
631
+ throw new Error('Invalid name');
632
+ }
633
+ const undername = name === baseName ? '@' : name.replace(`_${baseName}`, '');
634
+ const nameData = await this.getArNSRecord({ name: baseName });
635
+ const ant = ant_js_1.ANT.init({
636
+ process: new ao_process_js_1.AOProcess({
637
+ ao: this.process.ao,
638
+ processId: nameData.processId,
639
+ }),
640
+ });
641
+ const [owner, antRecord] = await Promise.all([
642
+ ant.getOwner(),
643
+ ant.getRecord({ undername }),
644
+ ]);
645
+ if (antRecord === undefined) {
646
+ throw new Error(`Record for ${undername} not found on ANT.`);
647
+ }
648
+ if (antRecord.ttlSeconds === undefined ||
649
+ antRecord.transactionId === undefined) {
650
+ throw new Error(`Invalid record on ANT. Must have ttlSeconds and transactionId. Record: ${JSON.stringify(antRecord)}`);
651
+ }
652
+ return {
653
+ name: name,
654
+ owner: owner,
655
+ txId: antRecord.transactionId,
656
+ ttlSeconds: antRecord.ttlSeconds,
657
+ priority: antRecord.priority,
658
+ // NOTE: we may want return the actual index of the record based on sorting in case ANT tries to set duplicate priority values to get around undername limits
659
+ processId: nameData.processId,
660
+ undernameLimit: nameData.undernameLimit,
661
+ type: nameData.type,
662
+ };
663
+ }
627
664
  }
628
665
  exports.ARIOReadable = ARIOReadable;
629
666
  class ARIOWriteable extends ARIOReadable {
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TrustedGatewaysHashProvider = void 0;
4
+ const arioGatewayHeaders = {
5
+ digest: 'x-ar-io-digest',
6
+ verified: 'x-ar-io-verified',
7
+ txId: 'x-arns-resolved-tx-id',
8
+ processId: 'x-arns-resolved-process-id',
9
+ };
10
+ class TrustedGatewaysHashProvider {
11
+ gatewaysProvider;
12
+ constructor({ gatewaysProvider,
13
+ // TODO: add threshold for allowed hash difference (i.e. by count or ratio of total gateways checked)
14
+ }) {
15
+ this.gatewaysProvider = gatewaysProvider;
16
+ }
17
+ /**
18
+ * Gets the digest for a given txId from all trusted gateways and ensures they all match.
19
+ * @param txId - The txId to get the digest for.
20
+ * @returns The digest for the given txId.
21
+ */
22
+ async getHash({ txId, }) {
23
+ // get the hash from every gateway, and ensure they all match
24
+ const hashSet = new Set();
25
+ const hashResults = [];
26
+ const gateways = await this.gatewaysProvider.getGateways();
27
+ const hashes = await Promise.all(gateways.map(async (gateway) => {
28
+ const response = await fetch(`${gateway.toString()}${txId}`, {
29
+ method: 'HEAD',
30
+ redirect: 'follow',
31
+ });
32
+ if (!response.ok) {
33
+ // skip this gateway
34
+ return undefined;
35
+ }
36
+ const txIdHash = response.headers.get(arioGatewayHeaders.digest);
37
+ if (txIdHash === null || txIdHash === undefined) {
38
+ // skip this gateway
39
+ return undefined;
40
+ }
41
+ hashResults.push({
42
+ gateway: gateway.hostname,
43
+ txIdHash,
44
+ });
45
+ return txIdHash;
46
+ }));
47
+ for (const hash of hashes) {
48
+ if (hash !== undefined) {
49
+ hashSet.add(hash);
50
+ }
51
+ }
52
+ if (hashSet.size === 0) {
53
+ throw new Error(`No trusted gateways found for txId ${txId}`);
54
+ }
55
+ if (hashSet.size > 1) {
56
+ throw new Error(`Failed to get consistent hash from all trusted gateways. ${JSON.stringify(hashResults)}`);
57
+ }
58
+ return { hash: hashResults[0].txIdHash, algorithm: 'sha256' };
59
+ }
60
+ /**
61
+ * Get the data root for a given txId from all trusted gateways and ensure they all match.
62
+ * @param txId - The txId to get the data root for.
63
+ * @returns The data root for the given txId.
64
+ */
65
+ async getDataRoot({ txId }) {
66
+ const dataRootSet = new Set();
67
+ const dataRootResults = [];
68
+ const gateways = await this.gatewaysProvider.getGateways();
69
+ const dataRoots = await Promise.all(gateways.map(async (gateway) => {
70
+ const response = await fetch(`${gateway.toString()}tx/${txId}/data_root`);
71
+ if (!response.ok) {
72
+ // skip this gateway
73
+ return undefined;
74
+ }
75
+ const dataRoot = await response.text();
76
+ dataRootResults.push({
77
+ gateway: gateway.hostname,
78
+ dataRoot,
79
+ });
80
+ return dataRoot;
81
+ }));
82
+ for (const dataRoot of dataRoots) {
83
+ if (dataRoot !== undefined) {
84
+ dataRootSet.add(dataRoot);
85
+ }
86
+ }
87
+ if (dataRootSet.size > 1) {
88
+ throw new Error(`Failed to get consistent data root from all trusted gateways. ${JSON.stringify(dataRootResults)}`);
89
+ }
90
+ return dataRootSet.values().next().value;
91
+ }
92
+ }
93
+ exports.TrustedGatewaysHashProvider = TrustedGatewaysHashProvider;
94
+ // client could check hashes of data items, match expected hash
95
+ // if the gateway has the hash and they've verified it, you can trust the data item and offset
96
+ // you would be only trusting the gateway that it is a valid bundle
97
+ // you can request the offset from the gateway to verify the id
98
+ /**
99
+ * Note from @djwhitt
100
+ *
101
+ * Calculating data roots this way is fine, but it may not reproduce the original data root.
102
+ * We could also implement a data root verifier that pulls all the chunks, checks that they
103
+ * reproduce the expected data root, and then compares the concatenated chunk data to the
104
+ * original data retrieved. That would take a while, but it should be able to verify any L1
105
+ * data where we can find the chunks.
106
+ */
@@ -36,3 +36,9 @@ __exportStar(require("./routers/priority.js"), exports);
36
36
  __exportStar(require("./routers/static.js"), exports);
37
37
  // gateways providers
38
38
  __exportStar(require("./gateways.js"), exports);
39
+ // trusted gateways
40
+ __exportStar(require("./gateways/trusted-gateways.js"), exports);
41
+ // hash providers
42
+ __exportStar(require("./verification/data-root-verifier.js"), exports);
43
+ __exportStar(require("./verification/hash-verifier.js"), exports);
44
+ // TODO: signature verification