@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.
@@ -813,8 +813,10 @@ const utils_js_1 = require("./utils.js");
813
813
  });
814
814
  },
815
815
  });
816
- if (process.argv[1].includes('bin/ar.io') || // Running from global .bin
817
- process.argv[1].includes('cli/cli') // Running from source
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
  }
@@ -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: 'http://localhost:6363', // default to ardrive cu for ARIO process
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 = result.Messages?.[0]?.Data;
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({ tags: filteredTags });
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
- intent = await this.getIntentByANTId(antId).catch((getIntentError) => {
345
- 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) {
346
380
  const intentError = new Error('An intent already exists for this ANT ID but failed to get intent:\n\n' +
347
- getIntentError.message);
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
- antTransferResult = await ant.transfer({
395
- target: this.process.processId,
396
- removeControllers: false, // important: do not remove the controllers of the ANT to prevent loss of control
397
- }, {
398
- tags: [{ name: 'X-Intent-Id', value: intent.intentId }],
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 tries = 0;
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
- console.log(new Error('Failed to get order: ' + error.message));
486
+ this.logger.warn(`Failed to get order: ${error.message}`);
433
487
  return null;
434
488
  });
435
- if (order === null) {
436
- await new Promise((resolve) => setTimeout(resolve, 1000));
489
+ if (order !== null) {
490
+ break;
491
+ }
492
+ if (attempt < maxRetries) {
437
493
  this.logger.info(`Waiting for order to be created...`);
438
- if (tries === 5) {
439
- this.logger.error(`Failed to get order after ${tries} attempts`);
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
  /**
@@ -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';
@@ -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.1';
20
+ exports.version = '3.24.0-solana.1';
@@ -811,8 +811,10 @@ makeCommand({
811
811
  });
812
812
  },
813
813
  });
814
- if (process.argv[1].includes('bin/ar.io') || // Running from global .bin
815
- process.argv[1].includes('cli/cli') // Running from source
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
  }
@@ -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: 'http://localhost:6363', // default to ardrive cu for ARIO process
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 = result.Messages?.[0]?.Data;
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({ tags: filteredTags });
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
- intent = await this.getIntentByANTId(antId).catch((getIntentError) => {
339
- 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) {
340
374
  const intentError = new Error('An intent already exists for this ANT ID but failed to get intent:\n\n' +
341
- getIntentError.message);
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
- antTransferResult = await ant.transfer({
389
- target: this.process.processId,
390
- removeControllers: false, // important: do not remove the controllers of the ANT to prevent loss of control
391
- }, {
392
- tags: [{ name: 'X-Intent-Id', value: intent.intentId }],
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 tries = 0;
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
- console.log(new Error('Failed to get order: ' + error.message));
480
+ this.logger.warn(`Failed to get order: ${error.message}`);
427
481
  return null;
428
482
  });
429
- if (order === null) {
430
- await new Promise((resolve) => setTimeout(resolve, 1000));
483
+ if (order !== null) {
484
+ break;
485
+ }
486
+ if (attempt < maxRetries) {
431
487
  this.logger.info(`Waiting for order to be created...`);
432
- if (tries === 5) {
433
- this.logger.error(`Failed to get order after ${tries} attempts`);
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
  /**
@@ -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';
@@ -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.1';
17
+ export const version = '3.24.0-solana.1';
@@ -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;
@@ -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";
@@ -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";
16
+ export declare const version = "4.0.0-solana.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/sdk",
3
- "version": "3.23.1",
3
+ "version": "3.24.0-solana.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ar-io/ar-io-sdk.git"