@ar.io/sdk 3.23.1 → 3.24.0-solana.1
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/lib/cjs/cli/cli.js +4 -2
- package/lib/cjs/cli/utils.js +1 -2
- package/lib/cjs/common/contracts/ao-process.js +6 -4
- package/lib/cjs/common/marketplace.js +79 -24
- package/lib/cjs/constants.js +2 -1
- package/lib/cjs/version.js +1 -1
- package/lib/esm/cli/cli.js +4 -2
- package/lib/esm/cli/utils.js +2 -3
- package/lib/esm/common/contracts/ao-process.js +6 -4
- package/lib/esm/common/marketplace.js +79 -24
- package/lib/esm/constants.js +1 -0
- package/lib/esm/version.js +1 -1
- package/lib/types/common/contracts/ao-process.d.ts +16 -2
- package/lib/types/common/marketplace.d.ts +14 -2
- package/lib/types/constants.d.ts +1 -0
- package/lib/types/version.d.ts +1 -1
- package/package.json +1 -1
package/lib/cjs/cli/cli.js
CHANGED
|
@@ -813,8 +813,10 @@ const utils_js_1 = require("./utils.js");
|
|
|
813
813
|
});
|
|
814
814
|
},
|
|
815
815
|
});
|
|
816
|
-
|
|
817
|
-
|
|
816
|
+
// Normalize separators so includes() works on Windows (argv uses backslashes).
|
|
817
|
+
const argvScript = process.argv[1].replace(/\\/g, '/');
|
|
818
|
+
if (argvScript.includes('bin/ar.io') || // Running from global .bin
|
|
819
|
+
argvScript.includes('cli/cli') // Running from source
|
|
818
820
|
) {
|
|
819
821
|
commander_1.program.parse(process.argv);
|
|
820
822
|
}
|
package/lib/cjs/cli/utils.js
CHANGED
|
@@ -198,8 +198,7 @@ function readARIOFromOptions(options) {
|
|
|
198
198
|
return index_js_1.ARIO.init({
|
|
199
199
|
hyperbeamUrl: options.hyperbeamUrl,
|
|
200
200
|
process: aoProcessFromOptions({
|
|
201
|
-
cuUrl:
|
|
202
|
-
//cuUrl: 'https://cu.ardrive.io', // default to ardrive cu for ARIO process
|
|
201
|
+
cuUrl: index_js_1.DEFAULT_CU_URL,
|
|
203
202
|
...options,
|
|
204
203
|
}),
|
|
205
204
|
paymentUrl: options.paymentUrl,
|
|
@@ -40,7 +40,7 @@ class AOProcess {
|
|
|
40
40
|
messageData === '' ||
|
|
41
41
|
messageData === null);
|
|
42
42
|
}
|
|
43
|
-
async read({ tags, retries = 3, fromAddress, }) {
|
|
43
|
+
async read({ tags, retries = 3, fromAddress, select, }) {
|
|
44
44
|
this.logger.debug(`Evaluating read interaction on process`, {
|
|
45
45
|
tags,
|
|
46
46
|
processId: this.processId,
|
|
@@ -105,7 +105,9 @@ class AOProcess {
|
|
|
105
105
|
throw new Error(result.message ||
|
|
106
106
|
`Process ${this.processId} did not return a valid response. Response: ${JSON.stringify(result)}`);
|
|
107
107
|
}
|
|
108
|
-
const messageData =
|
|
108
|
+
const messageData = select
|
|
109
|
+
? result.Messages.find(select)?.Data
|
|
110
|
+
: result.Messages?.[0]?.Data;
|
|
109
111
|
// return undefined if no data is returned
|
|
110
112
|
if (this.isMessageDataEmpty(messageData)) {
|
|
111
113
|
return undefined;
|
|
@@ -113,7 +115,7 @@ class AOProcess {
|
|
|
113
115
|
const response = (0, json_js_1.safeDecode)(messageData);
|
|
114
116
|
return response;
|
|
115
117
|
}
|
|
116
|
-
async send({ tags, data, signer, retries = 3, }) {
|
|
118
|
+
async send({ tags, data, signer, retries = 3, select, }) {
|
|
117
119
|
let messageId;
|
|
118
120
|
const anchor = (0, base64_js_1.getRandomText)(32); // anchor is a random text produce non-deterministic messages IDs when deterministic signers are provided (ETH)
|
|
119
121
|
try {
|
|
@@ -210,7 +212,7 @@ class AOProcess {
|
|
|
210
212
|
if (this.isMessageDataEmpty(result.Messages[0].Data)) {
|
|
211
213
|
return { id: messageId };
|
|
212
214
|
}
|
|
213
|
-
const resultData = (0, json_js_1.safeDecode)(result.Messages[0].Data);
|
|
215
|
+
const resultData = (0, json_js_1.safeDecode)(select ? result.Messages.find(select)?.Data : result.Messages[0].Data);
|
|
214
216
|
this.logger.debug('Message result data', {
|
|
215
217
|
resultData,
|
|
216
218
|
messageId,
|
|
@@ -35,6 +35,7 @@ class ArNSMarketplaceRead {
|
|
|
35
35
|
async getInfo() {
|
|
36
36
|
return this.process.read({
|
|
37
37
|
tags: [{ name: 'Action', value: 'Info' }],
|
|
38
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Info-Notice'),
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
async getPaginatedIntents({ cursor, limit, sortBy, sortOrder, filters, } = {}) {
|
|
@@ -49,6 +50,8 @@ class ArNSMarketplaceRead {
|
|
|
49
50
|
const filteredTags = tags.filter((tag) => tag.value !== undefined);
|
|
50
51
|
return this.process.read({
|
|
51
52
|
tags: filteredTags,
|
|
53
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' &&
|
|
54
|
+
tag.value === 'Get-Paginated-Intents-Notice'),
|
|
52
55
|
});
|
|
53
56
|
}
|
|
54
57
|
async getIntent(intentId) {
|
|
@@ -57,6 +60,7 @@ class ArNSMarketplaceRead {
|
|
|
57
60
|
{ name: 'Action', value: 'Get-Intent-By-Id' },
|
|
58
61
|
{ name: 'Intent-Id', value: intentId },
|
|
59
62
|
],
|
|
63
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Get-Intent-By-Id-Notice'),
|
|
60
64
|
});
|
|
61
65
|
}
|
|
62
66
|
async getIntentByANTId(antId) {
|
|
@@ -92,7 +96,10 @@ class ArNSMarketplaceRead {
|
|
|
92
96
|
},
|
|
93
97
|
];
|
|
94
98
|
const filteredTags = tags.filter((tag) => tag.value !== undefined);
|
|
95
|
-
return this.process.read({
|
|
99
|
+
return this.process.read({
|
|
100
|
+
tags: filteredTags,
|
|
101
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Get-Orders-Notice'),
|
|
102
|
+
});
|
|
96
103
|
}
|
|
97
104
|
/**
|
|
98
105
|
* Get a single order by ID
|
|
@@ -105,6 +112,7 @@ class ArNSMarketplaceRead {
|
|
|
105
112
|
{ name: 'Action', value: 'Get-Order' },
|
|
106
113
|
{ name: 'Order-Id', value: orderId },
|
|
107
114
|
],
|
|
115
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Get-Order-Notice'),
|
|
108
116
|
});
|
|
109
117
|
}
|
|
110
118
|
async getOrderByANTId(antId) {
|
|
@@ -127,6 +135,8 @@ class ArNSMarketplaceRead {
|
|
|
127
135
|
{ name: 'Action', value: 'Get-Paginated-Balances' },
|
|
128
136
|
...(0, index_js_1.paginationParamsToTags)(params),
|
|
129
137
|
],
|
|
138
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' &&
|
|
139
|
+
tag.value === 'Get-Paginated-Balances-Notice'),
|
|
130
140
|
});
|
|
131
141
|
}
|
|
132
142
|
/**
|
|
@@ -138,6 +148,7 @@ class ArNSMarketplaceRead {
|
|
|
138
148
|
{ name: 'Action', value: 'Get-Balance' },
|
|
139
149
|
{ name: 'Address', value: address },
|
|
140
150
|
],
|
|
151
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Get-Balance-Notice'),
|
|
141
152
|
});
|
|
142
153
|
}
|
|
143
154
|
async getUserAssets({ address, arioProcessId, }) {
|
|
@@ -238,6 +249,7 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
238
249
|
{ name: 'Quantity', value: params.amount },
|
|
239
250
|
],
|
|
240
251
|
signer: this.signer,
|
|
252
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Withdraw-Ario-Notice'),
|
|
241
253
|
});
|
|
242
254
|
}
|
|
243
255
|
async createIntent({ antId, orderType, quantity, price, expirationTime, minimumPrice, decreaseInterval, }) {
|
|
@@ -255,6 +267,7 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
255
267
|
return this.process.send({
|
|
256
268
|
tags: filteredTags,
|
|
257
269
|
signer: this.signer,
|
|
270
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Create-Intent-Notice'),
|
|
258
271
|
});
|
|
259
272
|
}
|
|
260
273
|
async pushANTIntentResolution(intentId) {
|
|
@@ -264,6 +277,8 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
264
277
|
{ name: 'X-Intent-Id', value: intentId },
|
|
265
278
|
],
|
|
266
279
|
signer: this.signer,
|
|
280
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' &&
|
|
281
|
+
tag.value === 'Push-ANT-Intent-Resolution-Notice'),
|
|
267
282
|
});
|
|
268
283
|
}
|
|
269
284
|
async settleAuction(params) {
|
|
@@ -277,11 +292,14 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
277
292
|
return this.process.send({
|
|
278
293
|
tags: filteredTags,
|
|
279
294
|
signer: this.signer,
|
|
295
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Settle-Auction-Notice'),
|
|
280
296
|
});
|
|
281
297
|
}
|
|
282
298
|
async listNameForSale({ name, expirationTime, price, type, walletAddress, minimumPrice, decreaseInterval, onProgress = (event) => {
|
|
283
299
|
this.logger.info(`List name for sale progress: ${event.step}`);
|
|
284
|
-
}, }) {
|
|
300
|
+
}, }, timeoutOptions) {
|
|
301
|
+
const maxRetries = timeoutOptions?.maxRetries ?? 15;
|
|
302
|
+
const statusPollIntervalMs = timeoutOptions?.statusPollIntervalMs ?? 3000;
|
|
285
303
|
// Get arns record for the current ant id associated with it
|
|
286
304
|
const record = await this.ario.getArNSRecord({ name: name });
|
|
287
305
|
this.logger.info(`Record ${name} found: ${JSON.stringify(record)}`);
|
|
@@ -341,10 +359,26 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
341
359
|
// check error for existing intent. Will be a contract error message.
|
|
342
360
|
const isExistingIntentError = error.message.includes('An intent already exists for this ANT ID');
|
|
343
361
|
if (isExistingIntentError) {
|
|
344
|
-
|
|
345
|
-
|
|
362
|
+
let fetchedIntent;
|
|
363
|
+
let lastIntentError = null;
|
|
364
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
365
|
+
try {
|
|
366
|
+
fetchedIntent = await this.getIntentByANTId(antId);
|
|
367
|
+
lastIntentError = null;
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
catch (getIntentError) {
|
|
371
|
+
lastIntentError = getIntentError;
|
|
372
|
+
this.logger.error(`Failed to get intent (attempt ${attempt + 1}/${maxRetries + 1}): ${getIntentError.message}`);
|
|
373
|
+
if (attempt < maxRetries) {
|
|
374
|
+
const backoffMs = statusPollIntervalMs * Math.pow(2, attempt);
|
|
375
|
+
await new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (lastIntentError !== null || fetchedIntent === undefined) {
|
|
346
380
|
const intentError = new Error('An intent already exists for this ANT ID but failed to get intent:\n\n' +
|
|
347
|
-
|
|
381
|
+
(lastIntentError?.message ?? 'Unknown error'));
|
|
348
382
|
onProgress({
|
|
349
383
|
step: 'error',
|
|
350
384
|
name,
|
|
@@ -353,7 +387,8 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
353
387
|
failedStep: 'creating-intent',
|
|
354
388
|
});
|
|
355
389
|
throw intentError;
|
|
356
|
-
}
|
|
390
|
+
}
|
|
391
|
+
intent = fetchedIntent;
|
|
357
392
|
}
|
|
358
393
|
else {
|
|
359
394
|
// Possible to get other errors, eg insufficient deposited ario balance. Rethrow them here.
|
|
@@ -391,12 +426,32 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
391
426
|
step: 'transferring-ant',
|
|
392
427
|
...transferAntEventData,
|
|
393
428
|
});
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
429
|
+
let transferResult;
|
|
430
|
+
let lastTransferError = null;
|
|
431
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
432
|
+
try {
|
|
433
|
+
transferResult = await ant.transfer({
|
|
434
|
+
target: this.process.processId,
|
|
435
|
+
removeControllers: false, // important: do not remove the controllers of the ANT to prevent loss of control
|
|
436
|
+
}, {
|
|
437
|
+
tags: [{ name: 'X-Intent-Id', value: intent.intentId }],
|
|
438
|
+
});
|
|
439
|
+
lastTransferError = null;
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
catch (error) {
|
|
443
|
+
lastTransferError = error;
|
|
444
|
+
this.logger.error(`Failed to transfer ANT (attempt ${attempt + 1}/${maxRetries + 1}): ${error.message}`);
|
|
445
|
+
if (attempt < maxRetries) {
|
|
446
|
+
const backoffMs = statusPollIntervalMs * Math.pow(2, attempt);
|
|
447
|
+
await new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (lastTransferError !== null || transferResult === undefined) {
|
|
452
|
+
throw lastTransferError ?? new Error('Failed to transfer ANT');
|
|
453
|
+
}
|
|
454
|
+
antTransferResult = transferResult;
|
|
400
455
|
this.logger.info(`ANT transferred: ${JSON.stringify(antTransferResult)}`);
|
|
401
456
|
onProgress({
|
|
402
457
|
step: 'ant-transferred',
|
|
@@ -425,24 +480,20 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
425
480
|
// This is to ensure the order is created before returning the result for ux purposes.
|
|
426
481
|
// This may still fail, in which case we return the intent and ant transfer result and handle the error in the client.
|
|
427
482
|
let order = null;
|
|
428
|
-
let
|
|
429
|
-
while (order === null && tries < 5) {
|
|
483
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
430
484
|
try {
|
|
431
485
|
order = await this.getOrderByANTId(antId).catch((error) => {
|
|
432
|
-
|
|
486
|
+
this.logger.warn(`Failed to get order: ${error.message}`);
|
|
433
487
|
return null;
|
|
434
488
|
});
|
|
435
|
-
if (order
|
|
436
|
-
|
|
489
|
+
if (order !== null) {
|
|
490
|
+
break;
|
|
491
|
+
}
|
|
492
|
+
if (attempt < maxRetries) {
|
|
437
493
|
this.logger.info(`Waiting for order to be created...`);
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
throw new Error(`Failed to get order after ${tries} attempts`);
|
|
441
|
-
}
|
|
442
|
-
tries++;
|
|
494
|
+
const backoffMs = statusPollIntervalMs * Math.pow(2, attempt);
|
|
495
|
+
await new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
443
496
|
}
|
|
444
|
-
// if the order is found, break the loop
|
|
445
|
-
break;
|
|
446
497
|
}
|
|
447
498
|
catch (error) {
|
|
448
499
|
this.logger.error(`Failed to get order: ${error.message}`);
|
|
@@ -499,6 +550,7 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
499
550
|
return this.process.send({
|
|
500
551
|
tags,
|
|
501
552
|
signer: this.signer,
|
|
553
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Cancel-Order-Notice'),
|
|
502
554
|
});
|
|
503
555
|
}
|
|
504
556
|
async createOrder({ swapToken, quantity, orderType, price, expirationTime, minimumPrice, decreaseInterval, transferDenomination, }) {
|
|
@@ -518,6 +570,7 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
518
570
|
return this.process.send({
|
|
519
571
|
tags: filteredTags,
|
|
520
572
|
signer: this.signer,
|
|
573
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Create-Order-Notice'),
|
|
521
574
|
});
|
|
522
575
|
}
|
|
523
576
|
async buyFixedPriceANT(params) {
|
|
@@ -590,6 +643,8 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
590
643
|
{ name: 'Bid-Amount', value: params.bidAmount },
|
|
591
644
|
],
|
|
592
645
|
signer: this.signer,
|
|
646
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' &&
|
|
647
|
+
tag.value === 'Bid-On-English-Auction-Notice'),
|
|
593
648
|
});
|
|
594
649
|
}
|
|
595
650
|
/**
|
package/lib/cjs/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_SCHEDULER_ID = exports.AO_AUTHORITY = exports.ANT_LUA_ID = exports.AOS_MODULE_ID = exports.MARIO_PER_ARIO = exports.MARKETPLACE_CONTRACT_ID = exports.ANT_REGISTRY_ID = exports.ANT_REGISTRY_TESTNET_ID = exports.ARIO_MAINNET_PROCESS_ID = exports.ARIO_TESTNET_PROCESS_ID = exports.arioDevnetProcessId = exports.ARIO_DEVNET_PROCESS_ID = exports.FQDN_REGEX = exports.ARWEAVE_TX_REGEX = void 0;
|
|
3
|
+
exports.DEFAULT_CU_URL = exports.DEFAULT_SCHEDULER_ID = exports.AO_AUTHORITY = exports.ANT_LUA_ID = exports.AOS_MODULE_ID = exports.MARIO_PER_ARIO = exports.MARKETPLACE_CONTRACT_ID = exports.ANT_REGISTRY_ID = exports.ANT_REGISTRY_TESTNET_ID = exports.ARIO_MAINNET_PROCESS_ID = exports.ARIO_TESTNET_PROCESS_ID = exports.arioDevnetProcessId = exports.ARIO_DEVNET_PROCESS_ID = exports.FQDN_REGEX = exports.ARWEAVE_TX_REGEX = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
6
6
|
*
|
|
@@ -38,3 +38,4 @@ exports.AOS_MODULE_ID = 'nEjlSFA_8narJlVHApbczDPkMc9znSqYtqtf1iOdoxM';
|
|
|
38
38
|
exports.ANT_LUA_ID = 'sOW9Sdm1yoPRrzerC5iu1nsupp4e6I-HnJyYVHzvzQo';
|
|
39
39
|
exports.AO_AUTHORITY = 'fcoN_xJeisVsPXA-trzVAuIiqO3ydLQxM-L4XbrQKzY';
|
|
40
40
|
exports.DEFAULT_SCHEDULER_ID = '_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA';
|
|
41
|
+
exports.DEFAULT_CU_URL = 'https://cu.ardrive.io';
|
package/lib/cjs/version.js
CHANGED
package/lib/esm/cli/cli.js
CHANGED
|
@@ -811,8 +811,10 @@ makeCommand({
|
|
|
811
811
|
});
|
|
812
812
|
},
|
|
813
813
|
});
|
|
814
|
-
|
|
815
|
-
|
|
814
|
+
// Normalize separators so includes() works on Windows (argv uses backslashes).
|
|
815
|
+
const argvScript = process.argv[1].replace(/\\/g, '/');
|
|
816
|
+
if (argvScript.includes('bin/ar.io') || // Running from global .bin
|
|
817
|
+
argvScript.includes('cli/cli') // Running from source
|
|
816
818
|
) {
|
|
817
819
|
program.parse(process.argv);
|
|
818
820
|
}
|
package/lib/esm/cli/utils.js
CHANGED
|
@@ -33,7 +33,7 @@ import { EthereumSigner } from '@dha-team/arbundles';
|
|
|
33
33
|
import { connect } from '@permaweb/aoconnect';
|
|
34
34
|
import { program } from 'commander';
|
|
35
35
|
import prompts from 'prompts';
|
|
36
|
-
import { ANT, ANTRegistry, ANT_REGISTRY_ID, ANT_REGISTRY_TESTNET_ID, AOProcess, ARIO, ARIOToken, ARIO_DEVNET_PROCESS_ID, ARIO_MAINNET_PROCESS_ID, ARIO_TESTNET_PROCESS_ID, ArweaveSigner, Logger, createAoSigner, fromB64Url, fundFromOptions, initANTStateForAddress, isValidFundFrom, isValidIntent, mARIOToken, sha256B64Url, validIntents, } from '../node/index.js';
|
|
36
|
+
import { ANT, ANTRegistry, ANT_REGISTRY_ID, ANT_REGISTRY_TESTNET_ID, AOProcess, ARIO, ARIOToken, ARIO_DEVNET_PROCESS_ID, ARIO_MAINNET_PROCESS_ID, ARIO_TESTNET_PROCESS_ID, ArweaveSigner, DEFAULT_CU_URL, Logger, createAoSigner, fromB64Url, fundFromOptions, initANTStateForAddress, isValidFundFrom, isValidIntent, mARIOToken, sha256B64Url, validIntents, } from '../node/index.js';
|
|
37
37
|
import { globalOptions } from './options.js';
|
|
38
38
|
export const defaultTtlSecondsCLI = 3600;
|
|
39
39
|
export function stringifyJsonForCLIDisplay(json) {
|
|
@@ -144,8 +144,7 @@ export function readARIOFromOptions(options) {
|
|
|
144
144
|
return ARIO.init({
|
|
145
145
|
hyperbeamUrl: options.hyperbeamUrl,
|
|
146
146
|
process: aoProcessFromOptions({
|
|
147
|
-
cuUrl:
|
|
148
|
-
//cuUrl: 'https://cu.ardrive.io', // default to ardrive cu for ARIO process
|
|
147
|
+
cuUrl: DEFAULT_CU_URL,
|
|
149
148
|
...options,
|
|
150
149
|
}),
|
|
151
150
|
paymentUrl: options.paymentUrl,
|
|
@@ -37,7 +37,7 @@ export class AOProcess {
|
|
|
37
37
|
messageData === '' ||
|
|
38
38
|
messageData === null);
|
|
39
39
|
}
|
|
40
|
-
async read({ tags, retries = 3, fromAddress, }) {
|
|
40
|
+
async read({ tags, retries = 3, fromAddress, select, }) {
|
|
41
41
|
this.logger.debug(`Evaluating read interaction on process`, {
|
|
42
42
|
tags,
|
|
43
43
|
processId: this.processId,
|
|
@@ -102,7 +102,9 @@ export class AOProcess {
|
|
|
102
102
|
throw new Error(result.message ||
|
|
103
103
|
`Process ${this.processId} did not return a valid response. Response: ${JSON.stringify(result)}`);
|
|
104
104
|
}
|
|
105
|
-
const messageData =
|
|
105
|
+
const messageData = select
|
|
106
|
+
? result.Messages.find(select)?.Data
|
|
107
|
+
: result.Messages?.[0]?.Data;
|
|
106
108
|
// return undefined if no data is returned
|
|
107
109
|
if (this.isMessageDataEmpty(messageData)) {
|
|
108
110
|
return undefined;
|
|
@@ -110,7 +112,7 @@ export class AOProcess {
|
|
|
110
112
|
const response = safeDecode(messageData);
|
|
111
113
|
return response;
|
|
112
114
|
}
|
|
113
|
-
async send({ tags, data, signer, retries = 3, }) {
|
|
115
|
+
async send({ tags, data, signer, retries = 3, select, }) {
|
|
114
116
|
let messageId;
|
|
115
117
|
const anchor = getRandomText(32); // anchor is a random text produce non-deterministic messages IDs when deterministic signers are provided (ETH)
|
|
116
118
|
try {
|
|
@@ -207,7 +209,7 @@ export class AOProcess {
|
|
|
207
209
|
if (this.isMessageDataEmpty(result.Messages[0].Data)) {
|
|
208
210
|
return { id: messageId };
|
|
209
211
|
}
|
|
210
|
-
const resultData = safeDecode(result.Messages[0].Data);
|
|
212
|
+
const resultData = safeDecode(select ? result.Messages.find(select)?.Data : result.Messages[0].Data);
|
|
211
213
|
this.logger.debug('Message result data', {
|
|
212
214
|
resultData,
|
|
213
215
|
messageId,
|
|
@@ -30,6 +30,7 @@ export class ArNSMarketplaceRead {
|
|
|
30
30
|
async getInfo() {
|
|
31
31
|
return this.process.read({
|
|
32
32
|
tags: [{ name: 'Action', value: 'Info' }],
|
|
33
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Info-Notice'),
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
36
|
async getPaginatedIntents({ cursor, limit, sortBy, sortOrder, filters, } = {}) {
|
|
@@ -44,6 +45,8 @@ export class ArNSMarketplaceRead {
|
|
|
44
45
|
const filteredTags = tags.filter((tag) => tag.value !== undefined);
|
|
45
46
|
return this.process.read({
|
|
46
47
|
tags: filteredTags,
|
|
48
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' &&
|
|
49
|
+
tag.value === 'Get-Paginated-Intents-Notice'),
|
|
47
50
|
});
|
|
48
51
|
}
|
|
49
52
|
async getIntent(intentId) {
|
|
@@ -52,6 +55,7 @@ export class ArNSMarketplaceRead {
|
|
|
52
55
|
{ name: 'Action', value: 'Get-Intent-By-Id' },
|
|
53
56
|
{ name: 'Intent-Id', value: intentId },
|
|
54
57
|
],
|
|
58
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Get-Intent-By-Id-Notice'),
|
|
55
59
|
});
|
|
56
60
|
}
|
|
57
61
|
async getIntentByANTId(antId) {
|
|
@@ -87,7 +91,10 @@ export class ArNSMarketplaceRead {
|
|
|
87
91
|
},
|
|
88
92
|
];
|
|
89
93
|
const filteredTags = tags.filter((tag) => tag.value !== undefined);
|
|
90
|
-
return this.process.read({
|
|
94
|
+
return this.process.read({
|
|
95
|
+
tags: filteredTags,
|
|
96
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Get-Orders-Notice'),
|
|
97
|
+
});
|
|
91
98
|
}
|
|
92
99
|
/**
|
|
93
100
|
* Get a single order by ID
|
|
@@ -100,6 +107,7 @@ export class ArNSMarketplaceRead {
|
|
|
100
107
|
{ name: 'Action', value: 'Get-Order' },
|
|
101
108
|
{ name: 'Order-Id', value: orderId },
|
|
102
109
|
],
|
|
110
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Get-Order-Notice'),
|
|
103
111
|
});
|
|
104
112
|
}
|
|
105
113
|
async getOrderByANTId(antId) {
|
|
@@ -122,6 +130,8 @@ export class ArNSMarketplaceRead {
|
|
|
122
130
|
{ name: 'Action', value: 'Get-Paginated-Balances' },
|
|
123
131
|
...paginationParamsToTags(params),
|
|
124
132
|
],
|
|
133
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' &&
|
|
134
|
+
tag.value === 'Get-Paginated-Balances-Notice'),
|
|
125
135
|
});
|
|
126
136
|
}
|
|
127
137
|
/**
|
|
@@ -133,6 +143,7 @@ export class ArNSMarketplaceRead {
|
|
|
133
143
|
{ name: 'Action', value: 'Get-Balance' },
|
|
134
144
|
{ name: 'Address', value: address },
|
|
135
145
|
],
|
|
146
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Get-Balance-Notice'),
|
|
136
147
|
});
|
|
137
148
|
}
|
|
138
149
|
async getUserAssets({ address, arioProcessId, }) {
|
|
@@ -232,6 +243,7 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
232
243
|
{ name: 'Quantity', value: params.amount },
|
|
233
244
|
],
|
|
234
245
|
signer: this.signer,
|
|
246
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Withdraw-Ario-Notice'),
|
|
235
247
|
});
|
|
236
248
|
}
|
|
237
249
|
async createIntent({ antId, orderType, quantity, price, expirationTime, minimumPrice, decreaseInterval, }) {
|
|
@@ -249,6 +261,7 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
249
261
|
return this.process.send({
|
|
250
262
|
tags: filteredTags,
|
|
251
263
|
signer: this.signer,
|
|
264
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Create-Intent-Notice'),
|
|
252
265
|
});
|
|
253
266
|
}
|
|
254
267
|
async pushANTIntentResolution(intentId) {
|
|
@@ -258,6 +271,8 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
258
271
|
{ name: 'X-Intent-Id', value: intentId },
|
|
259
272
|
],
|
|
260
273
|
signer: this.signer,
|
|
274
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' &&
|
|
275
|
+
tag.value === 'Push-ANT-Intent-Resolution-Notice'),
|
|
261
276
|
});
|
|
262
277
|
}
|
|
263
278
|
async settleAuction(params) {
|
|
@@ -271,11 +286,14 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
271
286
|
return this.process.send({
|
|
272
287
|
tags: filteredTags,
|
|
273
288
|
signer: this.signer,
|
|
289
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Settle-Auction-Notice'),
|
|
274
290
|
});
|
|
275
291
|
}
|
|
276
292
|
async listNameForSale({ name, expirationTime, price, type, walletAddress, minimumPrice, decreaseInterval, onProgress = (event) => {
|
|
277
293
|
this.logger.info(`List name for sale progress: ${event.step}`);
|
|
278
|
-
}, }) {
|
|
294
|
+
}, }, timeoutOptions) {
|
|
295
|
+
const maxRetries = timeoutOptions?.maxRetries ?? 15;
|
|
296
|
+
const statusPollIntervalMs = timeoutOptions?.statusPollIntervalMs ?? 3000;
|
|
279
297
|
// Get arns record for the current ant id associated with it
|
|
280
298
|
const record = await this.ario.getArNSRecord({ name: name });
|
|
281
299
|
this.logger.info(`Record ${name} found: ${JSON.stringify(record)}`);
|
|
@@ -335,10 +353,26 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
335
353
|
// check error for existing intent. Will be a contract error message.
|
|
336
354
|
const isExistingIntentError = error.message.includes('An intent already exists for this ANT ID');
|
|
337
355
|
if (isExistingIntentError) {
|
|
338
|
-
|
|
339
|
-
|
|
356
|
+
let fetchedIntent;
|
|
357
|
+
let lastIntentError = null;
|
|
358
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
359
|
+
try {
|
|
360
|
+
fetchedIntent = await this.getIntentByANTId(antId);
|
|
361
|
+
lastIntentError = null;
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
catch (getIntentError) {
|
|
365
|
+
lastIntentError = getIntentError;
|
|
366
|
+
this.logger.error(`Failed to get intent (attempt ${attempt + 1}/${maxRetries + 1}): ${getIntentError.message}`);
|
|
367
|
+
if (attempt < maxRetries) {
|
|
368
|
+
const backoffMs = statusPollIntervalMs * Math.pow(2, attempt);
|
|
369
|
+
await new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (lastIntentError !== null || fetchedIntent === undefined) {
|
|
340
374
|
const intentError = new Error('An intent already exists for this ANT ID but failed to get intent:\n\n' +
|
|
341
|
-
|
|
375
|
+
(lastIntentError?.message ?? 'Unknown error'));
|
|
342
376
|
onProgress({
|
|
343
377
|
step: 'error',
|
|
344
378
|
name,
|
|
@@ -347,7 +381,8 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
347
381
|
failedStep: 'creating-intent',
|
|
348
382
|
});
|
|
349
383
|
throw intentError;
|
|
350
|
-
}
|
|
384
|
+
}
|
|
385
|
+
intent = fetchedIntent;
|
|
351
386
|
}
|
|
352
387
|
else {
|
|
353
388
|
// Possible to get other errors, eg insufficient deposited ario balance. Rethrow them here.
|
|
@@ -385,12 +420,32 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
385
420
|
step: 'transferring-ant',
|
|
386
421
|
...transferAntEventData,
|
|
387
422
|
});
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
423
|
+
let transferResult;
|
|
424
|
+
let lastTransferError = null;
|
|
425
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
426
|
+
try {
|
|
427
|
+
transferResult = await ant.transfer({
|
|
428
|
+
target: this.process.processId,
|
|
429
|
+
removeControllers: false, // important: do not remove the controllers of the ANT to prevent loss of control
|
|
430
|
+
}, {
|
|
431
|
+
tags: [{ name: 'X-Intent-Id', value: intent.intentId }],
|
|
432
|
+
});
|
|
433
|
+
lastTransferError = null;
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
lastTransferError = error;
|
|
438
|
+
this.logger.error(`Failed to transfer ANT (attempt ${attempt + 1}/${maxRetries + 1}): ${error.message}`);
|
|
439
|
+
if (attempt < maxRetries) {
|
|
440
|
+
const backoffMs = statusPollIntervalMs * Math.pow(2, attempt);
|
|
441
|
+
await new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (lastTransferError !== null || transferResult === undefined) {
|
|
446
|
+
throw lastTransferError ?? new Error('Failed to transfer ANT');
|
|
447
|
+
}
|
|
448
|
+
antTransferResult = transferResult;
|
|
394
449
|
this.logger.info(`ANT transferred: ${JSON.stringify(antTransferResult)}`);
|
|
395
450
|
onProgress({
|
|
396
451
|
step: 'ant-transferred',
|
|
@@ -419,24 +474,20 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
419
474
|
// This is to ensure the order is created before returning the result for ux purposes.
|
|
420
475
|
// This may still fail, in which case we return the intent and ant transfer result and handle the error in the client.
|
|
421
476
|
let order = null;
|
|
422
|
-
let
|
|
423
|
-
while (order === null && tries < 5) {
|
|
477
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
424
478
|
try {
|
|
425
479
|
order = await this.getOrderByANTId(antId).catch((error) => {
|
|
426
|
-
|
|
480
|
+
this.logger.warn(`Failed to get order: ${error.message}`);
|
|
427
481
|
return null;
|
|
428
482
|
});
|
|
429
|
-
if (order
|
|
430
|
-
|
|
483
|
+
if (order !== null) {
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
if (attempt < maxRetries) {
|
|
431
487
|
this.logger.info(`Waiting for order to be created...`);
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
throw new Error(`Failed to get order after ${tries} attempts`);
|
|
435
|
-
}
|
|
436
|
-
tries++;
|
|
488
|
+
const backoffMs = statusPollIntervalMs * Math.pow(2, attempt);
|
|
489
|
+
await new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
437
490
|
}
|
|
438
|
-
// if the order is found, break the loop
|
|
439
|
-
break;
|
|
440
491
|
}
|
|
441
492
|
catch (error) {
|
|
442
493
|
this.logger.error(`Failed to get order: ${error.message}`);
|
|
@@ -493,6 +544,7 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
493
544
|
return this.process.send({
|
|
494
545
|
tags,
|
|
495
546
|
signer: this.signer,
|
|
547
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Cancel-Order-Notice'),
|
|
496
548
|
});
|
|
497
549
|
}
|
|
498
550
|
async createOrder({ swapToken, quantity, orderType, price, expirationTime, minimumPrice, decreaseInterval, transferDenomination, }) {
|
|
@@ -512,6 +564,7 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
512
564
|
return this.process.send({
|
|
513
565
|
tags: filteredTags,
|
|
514
566
|
signer: this.signer,
|
|
567
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' && tag.value === 'Create-Order-Notice'),
|
|
515
568
|
});
|
|
516
569
|
}
|
|
517
570
|
async buyFixedPriceANT(params) {
|
|
@@ -584,6 +637,8 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
|
|
|
584
637
|
{ name: 'Bid-Amount', value: params.bidAmount },
|
|
585
638
|
],
|
|
586
639
|
signer: this.signer,
|
|
640
|
+
select: (message) => message.Tags.some((tag) => tag.name === 'Action' &&
|
|
641
|
+
tag.value === 'Bid-On-English-Auction-Notice'),
|
|
587
642
|
});
|
|
588
643
|
}
|
|
589
644
|
/**
|
package/lib/esm/constants.js
CHANGED
|
@@ -35,3 +35,4 @@ export const AOS_MODULE_ID = 'nEjlSFA_8narJlVHApbczDPkMc9znSqYtqtf1iOdoxM';
|
|
|
35
35
|
export const ANT_LUA_ID = 'sOW9Sdm1yoPRrzerC5iu1nsupp4e6I-HnJyYVHzvzQo';
|
|
36
36
|
export const AO_AUTHORITY = 'fcoN_xJeisVsPXA-trzVAuIiqO3ydLQxM-L4XbrQKzY';
|
|
37
37
|
export const DEFAULT_SCHEDULER_ID = '_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA';
|
|
38
|
+
export const DEFAULT_CU_URL = 'https://cu.ardrive.io';
|
package/lib/esm/version.js
CHANGED
|
@@ -10,15 +10,22 @@ export declare class AOProcess implements AOContract {
|
|
|
10
10
|
logger?: ILogger;
|
|
11
11
|
});
|
|
12
12
|
private isMessageDataEmpty;
|
|
13
|
-
read<K>({ tags, retries, fromAddress, }: {
|
|
13
|
+
read<K>({ tags, retries, fromAddress, select, }: {
|
|
14
14
|
tags?: Array<{
|
|
15
15
|
name: string;
|
|
16
16
|
value: string;
|
|
17
17
|
}>;
|
|
18
18
|
retries?: number;
|
|
19
19
|
fromAddress?: string;
|
|
20
|
+
select?: (message: {
|
|
21
|
+
Data: string;
|
|
22
|
+
Tags: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
value: string;
|
|
25
|
+
}>;
|
|
26
|
+
}) => boolean;
|
|
20
27
|
}): Promise<K>;
|
|
21
|
-
send<K>({ tags, data, signer, retries, }: {
|
|
28
|
+
send<K>({ tags, data, signer, retries, select, }: {
|
|
22
29
|
tags: Array<{
|
|
23
30
|
name: string;
|
|
24
31
|
value: string;
|
|
@@ -26,6 +33,13 @@ export declare class AOProcess implements AOContract {
|
|
|
26
33
|
data?: string | undefined;
|
|
27
34
|
signer: AoSigner;
|
|
28
35
|
retries?: number;
|
|
36
|
+
select?: (message: {
|
|
37
|
+
Data: string;
|
|
38
|
+
Tags: Array<{
|
|
39
|
+
name: string;
|
|
40
|
+
value: string;
|
|
41
|
+
}>;
|
|
42
|
+
}) => boolean;
|
|
29
43
|
}): Promise<{
|
|
30
44
|
id: string;
|
|
31
45
|
result?: K;
|
|
@@ -301,6 +301,17 @@ export interface ListNameForSaleCompleteEvent {
|
|
|
301
301
|
* @experimental
|
|
302
302
|
*/
|
|
303
303
|
export type ListNameForSaleProgressEvent = CreatingIntentProgressEvent | IntentCreatedProgressEvent | TransferringAntProgressEvent | AntTransferredProgressEvent | ListNameForSaleErrorEvent | ListNameForSaleCompleteEvent;
|
|
304
|
+
/**
|
|
305
|
+
* Timeout and retry options for listNameForSale status checks and polling.
|
|
306
|
+
* Used when checking for intent (e.g. getIntentByANTId), transfer confirmation, and order listing.
|
|
307
|
+
* @experimental
|
|
308
|
+
*/
|
|
309
|
+
export interface ListNameForSaleTimeoutOptions {
|
|
310
|
+
/** Max retries when polling for intent, transfer confirmation, or order listing. Default 5. */
|
|
311
|
+
maxRetries?: number;
|
|
312
|
+
/** Base interval in ms for exponential backoff between status polls / retries. Wait time is base * 2^attempt. Default 1000. */
|
|
313
|
+
statusPollIntervalMs?: number;
|
|
314
|
+
}
|
|
304
315
|
/**
|
|
305
316
|
* Write interface for the ArNS marketplace
|
|
306
317
|
* @experimental
|
|
@@ -328,6 +339,7 @@ export interface AoArNSMarketplaceWrite {
|
|
|
328
339
|
/**
|
|
329
340
|
* List a name for sale on the marketplace
|
|
330
341
|
* @param params - Parameters including name, expiration time, price, type, wallet address, and optional auction parameters
|
|
342
|
+
* @param timeoutOptions - Optional retries and wait times for intent, transfer, and order listing status polling
|
|
331
343
|
* @returns Result containing intent, order, ANT transfer result, and any error
|
|
332
344
|
*/
|
|
333
345
|
listNameForSale({ name, expirationTime, price, type, walletAddress, minimumPrice, decreaseInterval, onProgress, }: {
|
|
@@ -339,7 +351,7 @@ export interface AoArNSMarketplaceWrite {
|
|
|
339
351
|
minimumPrice?: string;
|
|
340
352
|
decreaseInterval?: string;
|
|
341
353
|
onProgress?: (event: ListNameForSaleProgressEvent) => void;
|
|
342
|
-
}): Promise<{
|
|
354
|
+
}, timeoutOptions?: ListNameForSaleTimeoutOptions): Promise<{
|
|
343
355
|
intent: MarketplaceIntent;
|
|
344
356
|
order: Order | null;
|
|
345
357
|
antTransferResult: AoMessageResult<Record<string, string | number | boolean | null>> | null;
|
|
@@ -473,7 +485,7 @@ export declare class ArNSMarketplaceWrite extends ArNSMarketplaceRead implements
|
|
|
473
485
|
minimumPrice?: string;
|
|
474
486
|
decreaseInterval?: string;
|
|
475
487
|
onProgress?: (event: ListNameForSaleProgressEvent) => void;
|
|
476
|
-
}): Promise<{
|
|
488
|
+
}, timeoutOptions?: ListNameForSaleTimeoutOptions): Promise<{
|
|
477
489
|
intent: MarketplaceIntent;
|
|
478
490
|
order: Order | null;
|
|
479
491
|
antTransferResult: AoMessageResult<Record<string, string | number | boolean | null>> | null;
|
package/lib/types/constants.d.ts
CHANGED
|
@@ -34,3 +34,4 @@ export declare const AOS_MODULE_ID = "nEjlSFA_8narJlVHApbczDPkMc9znSqYtqtf1iOdox
|
|
|
34
34
|
export declare const ANT_LUA_ID = "sOW9Sdm1yoPRrzerC5iu1nsupp4e6I-HnJyYVHzvzQo";
|
|
35
35
|
export declare const AO_AUTHORITY = "fcoN_xJeisVsPXA-trzVAuIiqO3ydLQxM-L4XbrQKzY";
|
|
36
36
|
export declare const DEFAULT_SCHEDULER_ID = "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA";
|
|
37
|
+
export declare const DEFAULT_CU_URL = "https://cu.ardrive.io";
|
package/lib/types/version.d.ts
CHANGED