@ar.io/sdk 3.19.0-alpha.1 → 3.19.0-alpha.2

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.
@@ -634,6 +634,12 @@ const utils_js_1 = require("./utils.js");
634
634
  options: options_js_1.setAntUndernameOptions,
635
635
  action: antCommands_js_1.setAntRecordCLICommand,
636
636
  });
637
+ (0, utils_js_1.makeCommand)({
638
+ name: 'upgrade-ant',
639
+ description: 'Upgrade an ANT by forking it to the latest version and reassigning names',
640
+ options: options_js_1.upgradeAntOptions,
641
+ action: antCommands_js_1.upgradeAntCLICommand,
642
+ });
637
643
  (0, utils_js_1.makeCommand)({
638
644
  name: 'set-ant-ticker',
639
645
  description: 'Set the ticker of an ANT process',
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setAntRecordCLICommand = setAntRecordCLICommand;
4
4
  exports.setAntBaseNameCLICommand = setAntBaseNameCLICommand;
5
5
  exports.setAntUndernameCLICommand = setAntUndernameCLICommand;
6
+ exports.upgradeAntCLICommand = upgradeAntCLICommand;
6
7
  const utils_js_1 = require("../utils.js");
7
8
  /** @deprecated -- use set-ant-base-name and set-ant-undername */
8
9
  async function setAntRecordCLICommand(o) {
@@ -45,3 +46,35 @@ async function setAntUndernameCLICommand(o) {
45
46
  ttlSeconds,
46
47
  }, (0, utils_js_1.customTagsFromOptions)(o));
47
48
  }
49
+ async function upgradeAntCLICommand(o) {
50
+ const writeAnt = (0, utils_js_1.writeANTFromOptions)(o);
51
+ const arioProcessId = (0, utils_js_1.arioProcessIdFromOptions)(o);
52
+ const ario = (0, utils_js_1.readARIOFromOptions)(o);
53
+ const reassignAffiliatedNames = (0, utils_js_1.booleanFromOptions)(o, 'reassignAffiliatedNames');
54
+ const names = (0, utils_js_1.stringArrayFromOptions)(o, 'names') || [];
55
+ if (reassignAffiliatedNames) {
56
+ // Fetch all ArNS records that point to this ANT process
57
+ const allRecords = await ario.getArNSRecords({
58
+ filters: {
59
+ processId: writeAnt.processId,
60
+ },
61
+ });
62
+ // Filter records that belong to this ANT
63
+ const affiliatedNames = allRecords.items.map((record) => record.name);
64
+ names.push(...affiliatedNames);
65
+ }
66
+ if (names.length === 0) {
67
+ throw new Error('No names to reassign');
68
+ }
69
+ if (!o.skipConfirmation) {
70
+ await (0, utils_js_1.assertConfirmationPrompt)(`Upgrade all names affiliated with this ANT on ARIO process?\n` +
71
+ `ARIO Process ID: ${arioProcessId}\n` +
72
+ `ANT Process ID: ${writeAnt.processId}\n` +
73
+ `Names that will be reassigned (${names.length}): ${names.join(', ')}`, o);
74
+ }
75
+ return (0, utils_js_1.writeANTFromOptions)(o).upgrade({
76
+ reassignAffiliatedNames,
77
+ names,
78
+ arioProcessId,
79
+ });
80
+ }
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.setAntUndernameOptions = exports.setAntBaseNameOptions = exports.antStateOptions = exports.buyRecordOptions = exports.joinNetworkOptions = exports.updateGatewaySettingsOptions = exports.decreaseDelegateStakeOptions = exports.delegateStakeOptions = exports.redelegateStakeOptions = exports.operatorStakeOptions = exports.vaultedTransferOptions = exports.transferOptions = exports.tokenCostOptions = exports.getVaultOptions = exports.paginationAddressOptions = exports.paginationOptions = exports.nameWriteOptions = exports.addressAndVaultIdOptions = exports.epochOptions = exports.arnsPurchaseOptions = exports.writeActionOptions = exports.globalOptions = exports.walletOptions = exports.optionMap = void 0;
18
+ exports.upgradeAntOptions = exports.setAntUndernameOptions = exports.setAntBaseNameOptions = exports.antStateOptions = exports.buyRecordOptions = exports.joinNetworkOptions = exports.updateGatewaySettingsOptions = exports.decreaseDelegateStakeOptions = exports.delegateStakeOptions = exports.redelegateStakeOptions = exports.operatorStakeOptions = exports.vaultedTransferOptions = exports.transferOptions = exports.tokenCostOptions = exports.getVaultOptions = exports.paginationAddressOptions = exports.paginationOptions = exports.nameWriteOptions = exports.addressAndVaultIdOptions = exports.epochOptions = exports.arnsPurchaseOptions = exports.writeActionOptions = exports.globalOptions = exports.walletOptions = exports.optionMap = void 0;
19
19
  exports.optionMap = {
20
20
  walletFile: {
21
21
  alias: '-w, --wallet-file <walletFilePath>',
@@ -422,3 +422,4 @@ exports.setAntUndernameOptions = [
422
422
  ...exports.setAntBaseNameOptions,
423
423
  exports.optionMap.undername,
424
424
  ];
425
+ exports.upgradeAntOptions = [exports.optionMap.processId, ...exports.writeActionOptions];
@@ -9,11 +9,11 @@ exports.runCommand = runCommand;
9
9
  exports.applyOptions = applyOptions;
10
10
  exports.makeCommand = makeCommand;
11
11
  exports.arioProcessIdFromOptions = arioProcessIdFromOptions;
12
+ exports.antRegistryIdFromOptions = antRegistryIdFromOptions;
12
13
  exports.requiredJwkFromOptions = requiredJwkFromOptions;
13
14
  exports.jwkToAddress = jwkToAddress;
14
15
  exports.getLoggerFromOptions = getLoggerFromOptions;
15
16
  exports.readARIOFromOptions = readARIOFromOptions;
16
- exports.ANTRegistryProcessFromOptions = ANTRegistryProcessFromOptions;
17
17
  exports.readANTRegistryFromOptions = readANTRegistryFromOptions;
18
18
  exports.contractSignerFromOptions = contractSignerFromOptions;
19
19
  exports.requiredContractSignerFromOptions = requiredContractSignerFromOptions;
@@ -130,6 +130,15 @@ function arioProcessIdFromOptions({ arioProcessId, devnet, testnet, }) {
130
130
  }
131
131
  return index_js_1.ARIO_MAINNET_PROCESS_ID;
132
132
  }
133
+ function antRegistryIdFromOptions({ antRegistryProcessId, testnet, }) {
134
+ if (antRegistryProcessId !== undefined) {
135
+ return antRegistryProcessId;
136
+ }
137
+ if (testnet) {
138
+ return index_js_1.ANT_REGISTRY_TESTNET_ID;
139
+ }
140
+ return index_js_1.ANT_REGISTRY_ID;
141
+ }
133
142
  function walletFromOptions({ privateKey, walletFile, }) {
134
143
  if (privateKey !== undefined) {
135
144
  return JSON.parse(privateKey);
@@ -177,18 +186,9 @@ function readARIOFromOptions(options) {
177
186
  paymentUrl: options.paymentUrl,
178
187
  });
179
188
  }
180
- function ANTRegistryProcessFromOptions(options) {
181
- return new index_js_1.AOProcess({
182
- processId: options.antRegistryProcessId ?? index_js_1.ANT_REGISTRY_ID,
183
- ao: (0, aoconnect_1.connect)({
184
- MODE: 'legacy',
185
- CU_URL: options.cuUrl,
186
- }),
187
- });
188
- }
189
189
  function readANTRegistryFromOptions(options) {
190
190
  return index_js_1.ANTRegistry.init({
191
- process: ANTRegistryProcessFromOptions(options),
191
+ process: aoProcessFromOptions(options),
192
192
  hyperbeamUrl: options.hyperbeamUrl,
193
193
  });
194
194
  }
@@ -17,6 +17,8 @@ exports.AoANTWriteable = exports.AoANTReadable = exports.ANT = void 0;
17
17
  * limitations under the License.
18
18
  */
19
19
  const zod_1 = require("zod");
20
+ const constants_js_1 = require("../constants.js");
21
+ const constants_js_2 = require("../constants.js");
20
22
  const ant_js_1 = require("../types/ant.js");
21
23
  const index_js_1 = require("../types/index.js");
22
24
  const ant_js_2 = require("../utils/ant.js");
@@ -43,6 +45,97 @@ class ANT {
43
45
  * @param config
44
46
  */
45
47
  static fork = ao_js_1.forkANT;
48
+ /**
49
+ * Upgrade an ANT by forking it to the latest version and reassigning names.
50
+ *
51
+ *
52
+ * @param config Configuration object for the upgrade process
53
+ * @returns Promise resolving to the forked process ID and successfully reassigned names
54
+ */
55
+ static async upgrade({ signer, antProcessId, reassignAffiliatedNames = true, // if true, will reassign all affiliated names, otherwise will use the names parameter
56
+ names = [], arioProcessId = constants_js_1.ARIO_MAINNET_PROCESS_ID, antRegistryId = constants_js_2.ANT_REGISTRY_ID, ao, logger = index_js_2.Logger.default, skipVersionCheck = false, onSigningProgress, hyperbeamUrl, }) {
57
+ // if names is not empty but reassignAffiliatedNames it true, throw
58
+ if (names.length > 0 && reassignAffiliatedNames) {
59
+ throw new Error('Cannot reassign all affiliated names and provide specific names');
60
+ }
61
+ // get all the affiliated names if reassign all affiliated names is true
62
+ if (reassignAffiliatedNames) {
63
+ const ario = index_js_2.ARIO.init({
64
+ process: new index_js_2.AOProcess({ processId: arioProcessId, ao }),
65
+ });
66
+ onSigningProgress?.('fetching-affiliated-names', {
67
+ arioProcessId,
68
+ antProcessId,
69
+ });
70
+ const allAffiliatedNames = await ario.getArNSRecords({
71
+ filters: {
72
+ processId: antProcessId,
73
+ },
74
+ });
75
+ names.push(...allAffiliatedNames.items.map((record) => record.name));
76
+ }
77
+ // if names is empty and reassign all affiliated names is false, throw an error
78
+ if (names.length === 0) {
79
+ throw new Error('There are no names to reassign for this ANT.');
80
+ }
81
+ const existingAntProcess = ANT.init({
82
+ process: new index_js_2.AOProcess({
83
+ processId: antProcessId,
84
+ ao,
85
+ logger,
86
+ }),
87
+ hyperbeamUrl,
88
+ signer,
89
+ });
90
+ if (!skipVersionCheck) {
91
+ onSigningProgress?.('checking-version', {
92
+ antProcessId,
93
+ antRegistryId,
94
+ });
95
+ const isLatestVersion = await existingAntProcess.isLatestVersion({
96
+ antRegistryId,
97
+ });
98
+ if (isLatestVersion) {
99
+ return {
100
+ forkedProcessId: antProcessId,
101
+ reassignedNames: [],
102
+ failedReassignedNames: [],
103
+ };
104
+ }
105
+ }
106
+ const forkedProcessId = await ANT.fork({
107
+ signer,
108
+ antProcessId,
109
+ ao,
110
+ logger,
111
+ antRegistryId,
112
+ onSigningProgress,
113
+ });
114
+ // we could parallelize this, but then signing progress would be harder to track
115
+ const reassignedNames = [];
116
+ const failedReassignedNames = [];
117
+ for (const name of names) {
118
+ try {
119
+ onSigningProgress?.('reassigning-name', {
120
+ name,
121
+ arioProcessId,
122
+ antProcessId: forkedProcessId,
123
+ });
124
+ await existingAntProcess.reassignName({
125
+ name,
126
+ arioProcessId,
127
+ antProcessId: forkedProcessId,
128
+ });
129
+ reassignedNames.push(name);
130
+ }
131
+ catch (error) {
132
+ logger.error(`Failed to reassign name ${name}:`, { error });
133
+ // Continue with other names rather than failing completely
134
+ failedReassignedNames.push(name);
135
+ }
136
+ }
137
+ return { forkedProcessId, reassignedNames, failedReassignedNames };
138
+ }
46
139
  static init(config) {
47
140
  if (config !== undefined && 'signer' in config) {
48
141
  return new AoANTWriteable(config);
@@ -57,6 +150,8 @@ class AoANTReadable {
57
150
  strict;
58
151
  hyperbeamUrl;
59
152
  checkHyperBeamPromise;
153
+ moduleId;
154
+ moduleIdPromise;
60
155
  logger = index_js_2.Logger.default;
61
156
  constructor(config) {
62
157
  this.strict = config.strict || false;
@@ -189,6 +284,184 @@ class AoANTReadable {
189
284
  const info = await this.getInfo();
190
285
  return info.Logo;
191
286
  }
287
+ /**
288
+ * Gets the module ID of the current ANT process by querying its spawn transaction tags.
289
+ * Results are cached after the first successful fetch.
290
+ *
291
+ * @param graphqlUrl The GraphQL endpoint URL (defaults to Arweave's GraphQL endpoint)
292
+ * @param retries Number of retry attempts (defaults to 3)
293
+ * @returns Promise<string> The module ID used to spawn this ANT process
294
+ * @example
295
+ * ```ts
296
+ * const moduleId = await ant.getModuleId();
297
+ * console.log(`ANT was spawned with module: ${moduleId}`);
298
+ * ```
299
+ */
300
+ async getModuleId({
301
+ // TODO: we could use wayfinder for this
302
+ graphqlUrl = 'https://arweave.net/graphql', retries = 3, } = {}) {
303
+ // Return cached result if available
304
+ if (this.moduleId !== undefined) {
305
+ this.logger.debug('Returning cached module ID', {
306
+ processId: this.processId,
307
+ moduleId: this.moduleId,
308
+ });
309
+ return this.moduleId;
310
+ }
311
+ // Return existing promise if already in flight
312
+ if (this.moduleIdPromise) {
313
+ this.logger.debug('Returning in-flight module ID promise', {
314
+ processId: this.processId,
315
+ });
316
+ return this.moduleIdPromise;
317
+ }
318
+ // Create and cache the promise to prevent multiple concurrent requests
319
+ this.moduleIdPromise = this.fetchModuleId({ graphqlUrl, retries });
320
+ try {
321
+ const moduleId = await this.moduleIdPromise;
322
+ this.moduleId = moduleId;
323
+ this.logger.debug('Successfully fetched and cached module ID', {
324
+ processId: this.processId,
325
+ moduleId,
326
+ });
327
+ return moduleId;
328
+ }
329
+ finally {
330
+ // Clear the promise so future calls can retry if this one failed
331
+ this.moduleIdPromise = undefined;
332
+ }
333
+ }
334
+ /**
335
+ * Internal method to fetch the module ID from GraphQL.
336
+ *
337
+ * TODO: this could be more like get process headers/metadata and fetch additional details.
338
+ *
339
+ * It seems like module is the only relevant one, but scheduler and authority are also available.
340
+ */
341
+ async fetchModuleId({ graphqlUrl, retries, }) {
342
+ const query = JSON.stringify({
343
+ query: `
344
+ query {
345
+ transactions(
346
+ ids: ["${this.processId}"]
347
+ first: 1,
348
+ ) {
349
+ edges {
350
+ node {
351
+ tags {
352
+ name
353
+ value
354
+ }
355
+ }
356
+ }
357
+ }
358
+ }
359
+ `,
360
+ });
361
+ for (let i = 0; i < retries; i++) {
362
+ try {
363
+ const response = await fetch(graphqlUrl, {
364
+ method: 'POST',
365
+ body: query,
366
+ headers: {
367
+ 'Content-Type': 'application/json',
368
+ },
369
+ });
370
+ if (!response.ok) {
371
+ throw new Error(`GraphQL request failed: ${response.statusText}`);
372
+ }
373
+ const result = (await response.json());
374
+ if (result.errors) {
375
+ throw new Error(`GraphQL errors: ${result.errors.map((e) => e.message).join(', ')}`);
376
+ }
377
+ const edges = result.data?.transactions?.edges;
378
+ if (!edges || edges.length === 0) {
379
+ throw new Error(`No transaction found for process ID: ${this.processId}`);
380
+ }
381
+ const tags = edges[0].node.tags;
382
+ const moduleTag = tags.find((tag) => tag.name === 'Module');
383
+ if (!moduleTag) {
384
+ throw new Error(`No Module tag found for process ID: ${this.processId}`);
385
+ }
386
+ return moduleTag.value;
387
+ }
388
+ catch (error) {
389
+ if (i === retries - 1) {
390
+ // Final attempt failed
391
+ this.logger.error('Failed to get ANT module ID after all retries:', {
392
+ error,
393
+ });
394
+ throw new Error(`Unable to determine module ID for ANT process ${this.processId}: ${error.message}`);
395
+ }
396
+ // Exponential backoff
397
+ await new Promise((resolve) => setTimeout(resolve, Math.pow(2, i) * 1000));
398
+ }
399
+ }
400
+ throw new Error(`Unexpected error getting module ID for process ${this.processId}`);
401
+ }
402
+ /**
403
+ * Gets the version string of the current ANT by matching its module ID
404
+ * with versions from the ANT registry.
405
+ *
406
+ * @param antRegistryId The ANT registry process ID (defaults to mainnet registry)
407
+ * @param graphqlUrl The GraphQL endpoint URL for getModuleId (defaults to Arweave's GraphQL endpoint)
408
+ * @param retries Number of retry attempts for getModuleId (defaults to 3)
409
+ * @returns Promise<string> The version string (e.g., "1.0.15") or "unknown" if not found
410
+ * @example
411
+ * ```ts
412
+ * const version = await ant.getVersion();
413
+ * console.log(`ANT is running version: ${version}`);
414
+ * ```
415
+ */
416
+ async getVersion({ antRegistryId = constants_js_2.ANT_REGISTRY_ID, graphqlUrl = 'https://arweave.net/graphql', retries = 3, } = {}) {
417
+ // Get the current ANT's module ID
418
+ const currentModuleId = await this.getModuleId({ graphqlUrl, retries });
419
+ // Get all versions from the ANT registry
420
+ const antVersions = ant_versions_js_1.ANTVersions.init({
421
+ processId: antRegistryId,
422
+ });
423
+ const versions = await antVersions.getANTVersions();
424
+ // Find the version that matches our module ID
425
+ for (const [version, versionInfo] of Object.entries(versions)) {
426
+ if (versionInfo.moduleId === currentModuleId) {
427
+ this.logger.debug('Found matching ANT version', {
428
+ processId: this.processId,
429
+ moduleId: currentModuleId,
430
+ version,
431
+ });
432
+ return version;
433
+ }
434
+ }
435
+ const versionForModuleId = Object.entries(versions)
436
+ .map(([version, versionInfo]) => ({
437
+ version,
438
+ ...versionInfo,
439
+ }))
440
+ .find((obj) => obj.moduleId === currentModuleId);
441
+ return versionForModuleId?.version ?? 'unknown';
442
+ }
443
+ /**
444
+ * Checks if the current ANT version is the latest according to the ANT registry.
445
+ *
446
+ * @param antRegistryId Optional ANT registry process ID. Defaults to mainnet ANT registry.
447
+ * @param graphqlUrl Optional GraphQL endpoint. Defaults to https://arweave.net/graphql.
448
+ * @param retries Optional number of retries for fetching module ID. Defaults to 3.
449
+ * @returns {Promise<boolean>} True if current ANT version is the latest, false otherwise.
450
+ */
451
+ async isLatestVersion({ antRegistryId = constants_js_2.ANT_REGISTRY_ID, graphqlUrl = 'https://arweave.net/graphql', retries = 3, } = {}) {
452
+ // Get the current ANT's version
453
+ const currentVersion = await this.getVersion({
454
+ antRegistryId,
455
+ graphqlUrl,
456
+ retries,
457
+ });
458
+ // Get all versions from the ANT registry
459
+ const antVersions = ant_versions_js_1.ANTVersions.init({
460
+ processId: antRegistryId,
461
+ });
462
+ const latestVersion = await antVersions.getLatestANTVersion();
463
+ return currentVersion === latestVersion.version;
464
+ }
192
465
  /**
193
466
  * @param undername @type {string} The domain name.
194
467
  * @returns {Promise<ANTRecord>} The record of the undername domain.
@@ -721,5 +994,41 @@ class AoANTWriteable extends AoANTReadable {
721
994
  signer: this.signer,
722
995
  });
723
996
  }
997
+ /**
998
+ * Upgrade this ANT by forking it to the latest version and reassigning names.
999
+ *
1000
+ * This is a convenience method that calls the static ANT.upgrade() method
1001
+ * using this instance's process ID and signer.
1002
+ *
1003
+ * TODO: Add version checking by implementing a getVersion API on ANTs to compare
1004
+ * current version with latest ANT registry version and skip if already up to date.
1005
+ *
1006
+ * @param names @type {string[]} The ArNS names to reassign to the upgraded ANT.
1007
+ * @param arioProcessId @type {string} The processId of the ARIO contract.
1008
+ * @param antRegistryId @type {string} Optional ANT registry ID.
1009
+ * @param onSigningProgress Progress callback function.
1010
+ * @returns {Promise} The upgrade results.
1011
+ * @example
1012
+ * ```ts
1013
+ * const result = await ant.upgrade({
1014
+ * names: ["example", "test"],
1015
+ * arioProcessId: ARIO_MAINNET_PROCESS_ID
1016
+ * });
1017
+ * console.log(`Upgraded to process: ${result.forkedProcessId}`);
1018
+ * ```
1019
+ */
1020
+ async upgrade({ names, reassignAffiliatedNames, arioProcessId, antRegistryId, onSigningProgress, skipVersionCheck = false, }) {
1021
+ return ANT.upgrade({
1022
+ signer: this.signer,
1023
+ antProcessId: this.processId,
1024
+ ao: this.process.ao,
1025
+ names,
1026
+ reassignAffiliatedNames,
1027
+ arioProcessId,
1028
+ antRegistryId,
1029
+ onSigningProgress,
1030
+ skipVersionCheck,
1031
+ });
1032
+ }
724
1033
  }
725
1034
  exports.AoANTWriteable = AoANTWriteable;
@@ -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.ANT_REGISTRY_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_SCHEDULER_ID = exports.AO_AUTHORITY = exports.ANT_LUA_ID = exports.AOS_MODULE_ID = exports.MARIO_PER_ARIO = 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
  *
@@ -24,6 +24,7 @@ exports.ARIO_DEVNET_PROCESS_ID = 'GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc';
24
24
  exports.arioDevnetProcessId = exports.ARIO_DEVNET_PROCESS_ID;
25
25
  exports.ARIO_TESTNET_PROCESS_ID = 'agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoPdiA';
26
26
  exports.ARIO_MAINNET_PROCESS_ID = 'qNvAoz0TgcH7DMg8BCVn8jF32QH5L6T29VjHxhHqqGE';
27
+ exports.ANT_REGISTRY_TESTNET_ID = 'RR0vheYqtsKuJCWh6xj0beE35tjaEug5cejMw9n2aa8';
27
28
  exports.ANT_REGISTRY_ID = 'i_le_yKKPVstLTDSmkHRqf-wYphMnwB9OhleiTgMkWc';
28
29
  exports.MARIO_PER_ARIO = 1_000_000;
29
30
  /**
@@ -41,6 +41,9 @@ const sortANTRecords = (antRecords) => {
41
41
  return Object.fromEntries(sortedEntries.map(([a, aRecord], index) => [a, { ...aRecord, index }]));
42
42
  };
43
43
  exports.sortANTRecords = sortANTRecords;
44
+ /**
45
+ * @deprecated - this is no longer necessary because HyperBeam now uses the AoANTState type
46
+ */
44
47
  const isHyperBeamANTState = (state) => {
45
48
  return ('name' in state &&
46
49
  'ticker' in state &&
@@ -59,6 +62,7 @@ exports.isHyperBeamANTState = isHyperBeamANTState;
59
62
  /**
60
63
  * Convert HyperBeam serialized ANT state to backwards compatible format.
61
64
  *
65
+ * @deprecated - this is no longer necessary because HyperBeam now uses the AOANTState type
62
66
  * @param state - The HyperBeam serialized ANT state.
63
67
  */
64
68
  const convertHyperBeamStateToAoANTState = (initialState) => {
@@ -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.19.0-alpha.1';
20
+ exports.version = '3.19.0-alpha.2';
@@ -19,12 +19,12 @@ import { program } from 'commander';
19
19
  import { AOProcess, spawnANT } from '../node/index.js';
20
20
  import { mARIOToken } from '../types/token.js';
21
21
  import { version } from '../version.js';
22
- import { setAntBaseNameCLICommand, setAntRecordCLICommand, } from './commands/antCommands.js';
22
+ import { setAntBaseNameCLICommand, setAntRecordCLICommand, upgradeAntCLICommand, } from './commands/antCommands.js';
23
23
  import { buyRecordCLICommand, extendLeaseCLICommand, increaseUndernameLimitCLICommand, requestPrimaryNameCLICommand, setPrimaryNameCLICommand, upgradeRecordCLICommand, } from './commands/arnsPurchaseCommands.js';
24
24
  import { cancelWithdrawal, decreaseDelegateStake, decreaseOperatorStake, delegateStake, increaseOperatorStake, instantWithdrawal, joinNetwork, leaveNetwork, redelegateStake, saveObservations, updateGatewaySettings, } from './commands/gatewayWriteCommands.js';
25
25
  import { getAllGatewayVaults, getAllowedDelegates, getArNSRecord, getArNSReservedName, getArNSReturnedName, getCostDetails, getDelegations, getEpoch, getGateway, getGatewayDelegates, getGatewayVaults, getPrescribedNames, getPrescribedObservers, getPrimaryName, getTokenCost, getVault, listAllDelegatesCLICommand, listAntsForAddress, listArNSRecords, listArNSRecordsForAddress, listArNSReservedNames, listArNSReturnedNames, listGateways, resolveArNSName, } from './commands/readCommands.js';
26
26
  import { createVaultCLICommand, extendVaultCLICommand, increaseVaultCLICommand, revokeVaultCLICommand, transferCLICommand, vaultedTransferCLICommand, } from './commands/transfer.js';
27
- import { addressAndVaultIdOptions, antStateOptions, arnsPurchaseOptions, buyRecordOptions, decreaseDelegateStakeOptions, delegateStakeOptions, epochOptions, getVaultOptions, globalOptions, joinNetworkOptions, operatorStakeOptions, optionMap, paginationAddressOptions, paginationOptions, redelegateStakeOptions, setAntBaseNameOptions, setAntUndernameOptions, tokenCostOptions, transferOptions, updateGatewaySettingsOptions, vaultedTransferOptions, writeActionOptions, } from './options.js';
27
+ import { addressAndVaultIdOptions, antStateOptions, arnsPurchaseOptions, buyRecordOptions, decreaseDelegateStakeOptions, delegateStakeOptions, epochOptions, getVaultOptions, globalOptions, joinNetworkOptions, operatorStakeOptions, optionMap, paginationAddressOptions, paginationOptions, redelegateStakeOptions, setAntBaseNameOptions, setAntUndernameOptions, tokenCostOptions, transferOptions, updateGatewaySettingsOptions, upgradeAntOptions, vaultedTransferOptions, writeActionOptions, } from './options.js';
28
28
  import { applyOptions, arioProcessIdFromOptions, assertConfirmationPrompt, customTagsFromOptions, epochInputFromOptions, formatARIOWithCommas, getANTStateFromOptions, getLoggerFromOptions, makeCommand, paginationParamsFromOptions, readANTFromOptions, readARIOFromOptions, requiredAddressFromOptions, requiredAoSignerFromOptions, requiredProcessIdFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, writeANTFromOptions, } from './utils.js';
29
29
  applyOptions(program
30
30
  .name('ar.io')
@@ -632,6 +632,12 @@ makeCommand({
632
632
  options: setAntUndernameOptions,
633
633
  action: setAntRecordCLICommand,
634
634
  });
635
+ makeCommand({
636
+ name: 'upgrade-ant',
637
+ description: 'Upgrade an ANT by forking it to the latest version and reassigning names',
638
+ options: upgradeAntOptions,
639
+ action: upgradeAntCLICommand,
640
+ });
635
641
  makeCommand({
636
642
  name: 'set-ant-ticker',
637
643
  description: 'Set the ticker of an ANT process',
@@ -1,4 +1,4 @@
1
- import { assertConfirmationPrompt, customTagsFromOptions, defaultTtlSecondsCLI, requiredStringFromOptions, writeANTFromOptions, } from '../utils.js';
1
+ import { arioProcessIdFromOptions, assertConfirmationPrompt, booleanFromOptions, customTagsFromOptions, defaultTtlSecondsCLI, readARIOFromOptions, requiredStringFromOptions, stringArrayFromOptions, writeANTFromOptions, } from '../utils.js';
2
2
  /** @deprecated -- use set-ant-base-name and set-ant-undername */
3
3
  export async function setAntRecordCLICommand(o) {
4
4
  const ttlSeconds = +(o.ttlSeconds ?? defaultTtlSecondsCLI);
@@ -40,3 +40,35 @@ export async function setAntUndernameCLICommand(o) {
40
40
  ttlSeconds,
41
41
  }, customTagsFromOptions(o));
42
42
  }
43
+ export async function upgradeAntCLICommand(o) {
44
+ const writeAnt = writeANTFromOptions(o);
45
+ const arioProcessId = arioProcessIdFromOptions(o);
46
+ const ario = readARIOFromOptions(o);
47
+ const reassignAffiliatedNames = booleanFromOptions(o, 'reassignAffiliatedNames');
48
+ const names = stringArrayFromOptions(o, 'names') || [];
49
+ if (reassignAffiliatedNames) {
50
+ // Fetch all ArNS records that point to this ANT process
51
+ const allRecords = await ario.getArNSRecords({
52
+ filters: {
53
+ processId: writeAnt.processId,
54
+ },
55
+ });
56
+ // Filter records that belong to this ANT
57
+ const affiliatedNames = allRecords.items.map((record) => record.name);
58
+ names.push(...affiliatedNames);
59
+ }
60
+ if (names.length === 0) {
61
+ throw new Error('No names to reassign');
62
+ }
63
+ if (!o.skipConfirmation) {
64
+ await assertConfirmationPrompt(`Upgrade all names affiliated with this ANT on ARIO process?\n` +
65
+ `ARIO Process ID: ${arioProcessId}\n` +
66
+ `ANT Process ID: ${writeAnt.processId}\n` +
67
+ `Names that will be reassigned (${names.length}): ${names.join(', ')}`, o);
68
+ }
69
+ return writeANTFromOptions(o).upgrade({
70
+ reassignAffiliatedNames,
71
+ names,
72
+ arioProcessId,
73
+ });
74
+ }
@@ -419,3 +419,4 @@ export const setAntUndernameOptions = [
419
419
  ...setAntBaseNameOptions,
420
420
  optionMap.undername,
421
421
  ];
422
+ export const upgradeAntOptions = [optionMap.processId, ...writeActionOptions];
@@ -18,7 +18,7 @@ import { connect } from '@permaweb/aoconnect';
18
18
  import { program } from 'commander';
19
19
  import { readFileSync } from 'fs';
20
20
  import prompts from 'prompts';
21
- import { ANT, ANTRegistry, ANT_REGISTRY_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';
21
+ 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';
22
22
  import { globalOptions } from './options.js';
23
23
  export const defaultTtlSecondsCLI = 3600;
24
24
  export function stringifyJsonForCLIDisplay(json) {
@@ -78,6 +78,15 @@ export function arioProcessIdFromOptions({ arioProcessId, devnet, testnet, }) {
78
78
  }
79
79
  return ARIO_MAINNET_PROCESS_ID;
80
80
  }
81
+ export function antRegistryIdFromOptions({ antRegistryProcessId, testnet, }) {
82
+ if (antRegistryProcessId !== undefined) {
83
+ return antRegistryProcessId;
84
+ }
85
+ if (testnet) {
86
+ return ANT_REGISTRY_TESTNET_ID;
87
+ }
88
+ return ANT_REGISTRY_ID;
89
+ }
81
90
  function walletFromOptions({ privateKey, walletFile, }) {
82
91
  if (privateKey !== undefined) {
83
92
  return JSON.parse(privateKey);
@@ -125,18 +134,9 @@ export function readARIOFromOptions(options) {
125
134
  paymentUrl: options.paymentUrl,
126
135
  });
127
136
  }
128
- export function ANTRegistryProcessFromOptions(options) {
129
- return new AOProcess({
130
- processId: options.antRegistryProcessId ?? ANT_REGISTRY_ID,
131
- ao: connect({
132
- MODE: 'legacy',
133
- CU_URL: options.cuUrl,
134
- }),
135
- });
136
- }
137
137
  export function readANTRegistryFromOptions(options) {
138
138
  return ANTRegistry.init({
139
- process: ANTRegistryProcessFromOptions(options),
139
+ process: aoProcessFromOptions(options),
140
140
  hyperbeamUrl: options.hyperbeamUrl,
141
141
  });
142
142
  }