@ar.io/sdk 3.23.0-alpha.6 → 3.23.0-alpha.7

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.
@@ -297,7 +297,9 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
297
297
  }
298
298
  async listNameForSale({ name, expirationTime, price, type, walletAddress, minimumPrice, decreaseInterval, onProgress = (event) => {
299
299
  this.logger.info(`List name for sale progress: ${event.step}`);
300
- }, }) {
300
+ }, }, timeoutOptions) {
301
+ const maxRetries = timeoutOptions?.maxRetries ?? 15;
302
+ const statusPollIntervalMs = timeoutOptions?.statusPollIntervalMs ?? 3000;
301
303
  // Get arns record for the current ant id associated with it
302
304
  const record = await this.ario.getArNSRecord({ name: name });
303
305
  this.logger.info(`Record ${name} found: ${JSON.stringify(record)}`);
@@ -357,10 +359,26 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
357
359
  // check error for existing intent. Will be a contract error message.
358
360
  const isExistingIntentError = error.message.includes('An intent already exists for this ANT ID');
359
361
  if (isExistingIntentError) {
360
- intent = await this.getIntentByANTId(antId).catch((getIntentError) => {
361
- this.logger.error(`Failed to get intent: ${getIntentError.message}`);
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) {
362
380
  const intentError = new Error('An intent already exists for this ANT ID but failed to get intent:\n\n' +
363
- getIntentError.message);
381
+ (lastIntentError?.message ?? 'Unknown error'));
364
382
  onProgress({
365
383
  step: 'error',
366
384
  name,
@@ -369,7 +387,8 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
369
387
  failedStep: 'creating-intent',
370
388
  });
371
389
  throw intentError;
372
- });
390
+ }
391
+ intent = fetchedIntent;
373
392
  }
374
393
  else {
375
394
  // Possible to get other errors, eg insufficient deposited ario balance. Rethrow them here.
@@ -407,12 +426,32 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
407
426
  step: 'transferring-ant',
408
427
  ...transferAntEventData,
409
428
  });
410
- antTransferResult = await ant.transfer({
411
- target: this.process.processId,
412
- removeControllers: false, // important: do not remove the controllers of the ANT to prevent loss of control
413
- }, {
414
- tags: [{ name: 'X-Intent-Id', value: intent.intentId }],
415
- });
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;
416
455
  this.logger.info(`ANT transferred: ${JSON.stringify(antTransferResult)}`);
417
456
  onProgress({
418
457
  step: 'ant-transferred',
@@ -441,24 +480,20 @@ class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
441
480
  // This is to ensure the order is created before returning the result for ux purposes.
442
481
  // This may still fail, in which case we return the intent and ant transfer result and handle the error in the client.
443
482
  let order = null;
444
- let tries = 0;
445
- while (order === null && tries < 5) {
483
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
446
484
  try {
447
485
  order = await this.getOrderByANTId(antId).catch((error) => {
448
- console.log(new Error('Failed to get order: ' + error.message));
486
+ this.logger.warn(`Failed to get order: ${error.message}`);
449
487
  return null;
450
488
  });
451
- if (order === null) {
452
- await new Promise((resolve) => setTimeout(resolve, 1000));
489
+ if (order !== null) {
490
+ break;
491
+ }
492
+ if (attempt < maxRetries) {
453
493
  this.logger.info(`Waiting for order to be created...`);
454
- if (tries === 5) {
455
- this.logger.error(`Failed to get order after ${tries} attempts`);
456
- throw new Error(`Failed to get order after ${tries} attempts`);
457
- }
458
- tries++;
494
+ const backoffMs = statusPollIntervalMs * Math.pow(2, attempt);
495
+ await new Promise((resolve) => setTimeout(resolve, backoffMs));
459
496
  }
460
- // if the order is found, break the loop
461
- break;
462
497
  }
463
498
  catch (error) {
464
499
  this.logger.error(`Failed to get order: ${error.message}`);
@@ -17,4 +17,4 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.version = void 0;
19
19
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
20
- exports.version = '3.23.0-alpha.6';
20
+ exports.version = '3.23.0-alpha.7';
@@ -291,7 +291,9 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
291
291
  }
292
292
  async listNameForSale({ name, expirationTime, price, type, walletAddress, minimumPrice, decreaseInterval, onProgress = (event) => {
293
293
  this.logger.info(`List name for sale progress: ${event.step}`);
294
- }, }) {
294
+ }, }, timeoutOptions) {
295
+ const maxRetries = timeoutOptions?.maxRetries ?? 15;
296
+ const statusPollIntervalMs = timeoutOptions?.statusPollIntervalMs ?? 3000;
295
297
  // Get arns record for the current ant id associated with it
296
298
  const record = await this.ario.getArNSRecord({ name: name });
297
299
  this.logger.info(`Record ${name} found: ${JSON.stringify(record)}`);
@@ -351,10 +353,26 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
351
353
  // check error for existing intent. Will be a contract error message.
352
354
  const isExistingIntentError = error.message.includes('An intent already exists for this ANT ID');
353
355
  if (isExistingIntentError) {
354
- intent = await this.getIntentByANTId(antId).catch((getIntentError) => {
355
- this.logger.error(`Failed to get intent: ${getIntentError.message}`);
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) {
356
374
  const intentError = new Error('An intent already exists for this ANT ID but failed to get intent:\n\n' +
357
- getIntentError.message);
375
+ (lastIntentError?.message ?? 'Unknown error'));
358
376
  onProgress({
359
377
  step: 'error',
360
378
  name,
@@ -363,7 +381,8 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
363
381
  failedStep: 'creating-intent',
364
382
  });
365
383
  throw intentError;
366
- });
384
+ }
385
+ intent = fetchedIntent;
367
386
  }
368
387
  else {
369
388
  // Possible to get other errors, eg insufficient deposited ario balance. Rethrow them here.
@@ -401,12 +420,32 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
401
420
  step: 'transferring-ant',
402
421
  ...transferAntEventData,
403
422
  });
404
- antTransferResult = await ant.transfer({
405
- target: this.process.processId,
406
- removeControllers: false, // important: do not remove the controllers of the ANT to prevent loss of control
407
- }, {
408
- tags: [{ name: 'X-Intent-Id', value: intent.intentId }],
409
- });
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;
410
449
  this.logger.info(`ANT transferred: ${JSON.stringify(antTransferResult)}`);
411
450
  onProgress({
412
451
  step: 'ant-transferred',
@@ -435,24 +474,20 @@ export class ArNSMarketplaceWrite extends ArNSMarketplaceRead {
435
474
  // This is to ensure the order is created before returning the result for ux purposes.
436
475
  // This may still fail, in which case we return the intent and ant transfer result and handle the error in the client.
437
476
  let order = null;
438
- let tries = 0;
439
- while (order === null && tries < 5) {
477
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
440
478
  try {
441
479
  order = await this.getOrderByANTId(antId).catch((error) => {
442
- console.log(new Error('Failed to get order: ' + error.message));
480
+ this.logger.warn(`Failed to get order: ${error.message}`);
443
481
  return null;
444
482
  });
445
- if (order === null) {
446
- await new Promise((resolve) => setTimeout(resolve, 1000));
483
+ if (order !== null) {
484
+ break;
485
+ }
486
+ if (attempt < maxRetries) {
447
487
  this.logger.info(`Waiting for order to be created...`);
448
- if (tries === 5) {
449
- this.logger.error(`Failed to get order after ${tries} attempts`);
450
- throw new Error(`Failed to get order after ${tries} attempts`);
451
- }
452
- tries++;
488
+ const backoffMs = statusPollIntervalMs * Math.pow(2, attempt);
489
+ await new Promise((resolve) => setTimeout(resolve, backoffMs));
453
490
  }
454
- // if the order is found, break the loop
455
- break;
456
491
  }
457
492
  catch (error) {
458
493
  this.logger.error(`Failed to get order: ${error.message}`);
@@ -14,4 +14,4 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
17
- export const version = '3.23.0-alpha.6';
17
+ export const version = '3.23.0-alpha.7';
@@ -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;
@@ -13,4 +13,4 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- export declare const version = "3.23.0-alpha.5";
16
+ export declare const version = "3.23.0-alpha.6";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/sdk",
3
- "version": "3.23.0-alpha.6",
3
+ "version": "3.23.0-alpha.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ar-io/ar-io-sdk.git"