@ar.io/sdk 3.1.0-alpha.1 → 3.1.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.
@@ -19,11 +19,12 @@ import { program } from 'commander';
19
19
  import { spawnANT } from '../node/index.js';
20
20
  import { mARIOToken } from '../types/token.js';
21
21
  import { version } from '../version.js';
22
+ import { buyRecordCLICommand, extendLeaseCLICommand, increaseUndernameLimitCLICommand, requestPrimaryNameCLICommand, upgradeRecordCLICommand, } from './commands/arnsPurchaseCommands.js';
22
23
  import { cancelWithdrawal, decreaseDelegateStake, decreaseOperatorStake, delegateStake, increaseOperatorStake, instantWithdrawal, joinNetwork, leaveNetwork, redelegateStake, saveObservations, updateGatewaySettings, } from './commands/gatewayWriteCommands.js';
23
24
  import { getAllowedDelegates, getArNSRecord, getArNSReservedName, getArNSReturnedName, getCostDetails, getDelegations, getEpoch, getGateway, getGatewayDelegates, getGatewayVaults, getPrescribedNames, getPrescribedObservers, getPrimaryName, getTokenCost, getVault, listArNSRecords, listArNSReservedNames, listArNSReturnedNames, listGateways, } from './commands/readCommands.js';
24
25
  import { transfer } from './commands/transfer.js';
25
- import { addressAndVaultIdOptions, addressOptions, antStateOptions, buyRecordOptions, decreaseDelegateStakeOptions, delegateStakeOptions, epochOptions, getVaultOptions, globalOptions, initiatorOptions, joinNetworkOptions, nameOptions, nameWriteOptions, operatorStakeOptions, optionMap, paginationAddressOptions, paginationOptions, redelegateStakeOptions, tokenCostOptions, transferOptions, updateGatewaySettingsOptions, writeActionOptions, } from './options.js';
26
- import { applyOptions, arioProcessIdFromOptions, assertConfirmationPrompt, epochInputFromOptions, formatARIOWithCommas, getANTStateFromOptions, getLoggerFromOptions, makeCommand, paginationParamsFromOptions, positiveIntegerFromOptions, readANTFromOptions, readARIOFromOptions, recordTypeFromOptions, requiredAddressFromOptions, requiredAoSignerFromOptions, requiredPositiveIntegerFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, writeANTFromOptions, writeARIOFromOptions, writeActionTagsFromOptions, } from './utils.js';
26
+ import { addressAndVaultIdOptions, antStateOptions, arnsPurchaseOptions, buyRecordOptions, decreaseDelegateStakeOptions, delegateStakeOptions, epochOptions, getVaultOptions, globalOptions, joinNetworkOptions, operatorStakeOptions, optionMap, paginationAddressOptions, paginationOptions, redelegateStakeOptions, tokenCostOptions, transferOptions, updateGatewaySettingsOptions, writeActionOptions, } from './options.js';
27
+ import { applyOptions, arioProcessIdFromOptions, assertConfirmationPrompt, epochInputFromOptions, formatARIOWithCommas, getANTStateFromOptions, getLoggerFromOptions, makeCommand, paginationParamsFromOptions, readANTFromOptions, readARIOFromOptions, requiredAddressFromOptions, requiredAoSignerFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, writeANTFromOptions, writeActionTagsFromOptions, } from './utils.js';
27
28
  applyOptions(program
28
29
  .name('ar.io')
29
30
  .version(version)
@@ -52,7 +53,7 @@ makeCommand({
52
53
  makeCommand({
53
54
  name: 'get-gateway',
54
55
  description: 'Get the gateway of an address',
55
- options: addressOptions,
56
+ options: [optionMap.address],
56
57
  action: getGateway,
57
58
  });
58
59
  makeCommand({
@@ -70,7 +71,7 @@ makeCommand({
70
71
  makeCommand({
71
72
  name: 'get-delegations',
72
73
  description: 'Get all stake delegated to gateways from this address',
73
- options: addressOptions,
74
+ options: [optionMap.address],
74
75
  action: getDelegations,
75
76
  });
76
77
  makeCommand({
@@ -82,7 +83,7 @@ makeCommand({
82
83
  makeCommand({
83
84
  name: 'get-arns-record',
84
85
  description: 'Get an ArNS record by name',
85
- options: nameOptions,
86
+ options: [optionMap.name],
86
87
  action: getArNSRecord,
87
88
  });
88
89
  makeCommand({
@@ -94,7 +95,7 @@ makeCommand({
94
95
  makeCommand({
95
96
  name: 'get-arns-reserved-name',
96
97
  description: 'Get a reserved ArNS name',
97
- options: nameOptions,
98
+ options: [optionMap.name],
98
99
  action: getArNSReservedName,
99
100
  });
100
101
  makeCommand({
@@ -106,7 +107,7 @@ makeCommand({
106
107
  makeCommand({
107
108
  name: 'get-arns-returned-name',
108
109
  description: 'Get an ArNS returned name by name',
109
- options: nameOptions,
110
+ options: [optionMap.name],
110
111
  action: getArNSReturnedName,
111
112
  });
112
113
  makeCommand({
@@ -174,7 +175,7 @@ makeCommand({
174
175
  makeCommand({
175
176
  name: 'get-primary-name-request',
176
177
  description: 'Get primary name request',
177
- options: initiatorOptions,
178
+ options: [optionMap.initiator],
178
179
  action: (o) => readARIOFromOptions(o)
179
180
  .getPrimaryNameRequest({
180
181
  initiator: requiredStringFromOptions(o, 'initiator'),
@@ -194,7 +195,7 @@ makeCommand({
194
195
  makeCommand({
195
196
  name: 'get-primary-name',
196
197
  description: 'Get primary name',
197
- options: [...addressOptions, optionMap.name],
198
+ options: [optionMap.address, optionMap.name],
198
199
  action: getPrimaryName,
199
200
  });
200
201
  makeCommand({
@@ -208,7 +209,7 @@ makeCommand({
208
209
  makeCommand({
209
210
  name: 'balance',
210
211
  description: 'Get the balance of an address',
211
- options: addressOptions,
212
+ options: [optionMap.address],
212
213
  action: (options) => readARIOFromOptions(options)
213
214
  .getBalance({ address: requiredAddressFromOptions(options) })
214
215
  .then((result) => ({
@@ -228,7 +229,7 @@ makeCommand({
228
229
  makeCommand({
229
230
  name: 'get-redelegation-fee',
230
231
  description: 'Get redelegation fee',
231
- options: addressOptions,
232
+ options: [optionMap.address],
232
233
  action: (options) => readARIOFromOptions(options).getRedelegationFee({
233
234
  address: requiredAddressFromOptions(options),
234
235
  }),
@@ -324,82 +325,31 @@ makeCommand({
324
325
  name: 'buy-record',
325
326
  description: 'Buy a record',
326
327
  options: buyRecordOptions,
327
- action: async (options) => {
328
- const ario = writeARIOFromOptions(options).ario;
329
- const name = requiredStringFromOptions(options, 'name');
330
- const type = recordTypeFromOptions(options);
331
- const years = positiveIntegerFromOptions(options, 'years');
332
- // TODO: Assert balance is sufficient for action
333
- // TODO: Assert record is not already owned
334
- const processId = options.processId;
335
- if (processId === undefined) {
336
- // TODO: Spawn ANT process, register it to ANT registry, get process ID
337
- throw new Error('Process ID must be provided for buy-record');
338
- }
339
- await assertConfirmationPrompt(`Are you sure you want to ${type} the record ${name}?`, options);
340
- return ario.buyRecord({
341
- name: requiredStringFromOptions(options, 'name'),
342
- processId,
343
- type,
344
- years,
345
- });
346
- },
328
+ action: buyRecordCLICommand,
347
329
  });
348
330
  makeCommand({
349
331
  name: 'upgrade-record',
350
332
  description: 'Upgrade the lease of a record to a permabuy',
351
- options: [...nameOptions, ...writeActionOptions],
352
- // TODO: could assert record is leased by sender, assert balance is sufficient
353
- action: async (options) => {
354
- const name = requiredStringFromOptions(options, 'name');
355
- await assertConfirmationPrompt(`Are you sure you want to upgrade the lease of ${name} to a permabuy?`, options);
356
- return writeARIOFromOptions(options).ario.upgradeRecord({
357
- name,
358
- });
359
- },
333
+ options: arnsPurchaseOptions,
334
+ action: upgradeRecordCLICommand,
360
335
  });
361
336
  makeCommand({
362
337
  name: 'extend-lease',
363
338
  description: 'Extend the lease of a record',
364
- options: [...writeActionOptions, optionMap.name, optionMap.years],
365
- action: async (options) => {
366
- const name = requiredStringFromOptions(options, 'name');
367
- const years = requiredPositiveIntegerFromOptions(options, 'years');
368
- await assertConfirmationPrompt(`Are you sure you want to extend the lease of ${name} by ${years}?`, options);
369
- return writeARIOFromOptions(options).ario.extendLease({
370
- name,
371
- years,
372
- }, writeActionTagsFromOptions(options));
373
- },
339
+ options: [...arnsPurchaseOptions, optionMap.years],
340
+ action: extendLeaseCLICommand,
374
341
  });
375
342
  makeCommand({
376
343
  name: 'increase-undername-limit',
377
344
  description: 'Increase the limit of a name',
378
- options: [...writeActionOptions, optionMap.name, optionMap.increaseCount],
379
- action: async (options) => {
380
- const name = requiredStringFromOptions(options, 'name');
381
- const increaseCount = requiredPositiveIntegerFromOptions(options, 'increaseCount');
382
- await assertConfirmationPrompt(`Are you sure you want to increase the undername limit of ${name} by ${increaseCount}?`, options);
383
- return writeARIOFromOptions(options).ario.increaseUndernameLimit({
384
- name,
385
- increaseCount,
386
- }, writeActionTagsFromOptions(options));
387
- },
345
+ options: [...arnsPurchaseOptions, optionMap.increaseCount],
346
+ action: increaseUndernameLimitCLICommand,
388
347
  });
389
348
  makeCommand({
390
349
  name: 'request-primary-name',
391
350
  description: 'Request a primary name',
392
- options: nameWriteOptions,
393
- action: async (options) => {
394
- // TODO: Assert balance is sufficient for action?
395
- // TODO: Assert name requested is not already owned
396
- // TODO: More assertions?
397
- const name = requiredStringFromOptions(options, 'name');
398
- await assertConfirmationPrompt(`Are you sure you want to request the primary name ${name}?`, options);
399
- return writeARIOFromOptions(options).ario.requestPrimaryName({
400
- name,
401
- });
402
- },
351
+ options: arnsPurchaseOptions,
352
+ action: requestPrimaryNameCLICommand,
403
353
  });
404
354
  makeCommand({
405
355
  name: 'spawn-ant',
@@ -0,0 +1,159 @@
1
+ import { assertConfirmationPrompt, assertEnoughBalanceForArNSPurchase, fundFromFromOptions, positiveIntegerFromOptions, recordTypeFromOptions, requiredPositiveIntegerFromOptions, requiredStringFromOptions, writeARIOFromOptions, writeActionTagsFromOptions, } from '../utils.js';
2
+ export async function buyRecordCLICommand(o) {
3
+ const { ario, signerAddress } = writeARIOFromOptions(o);
4
+ const name = requiredStringFromOptions(o, 'name');
5
+ const type = recordTypeFromOptions(o);
6
+ const years = positiveIntegerFromOptions(o, 'years');
7
+ const fundFrom = fundFromFromOptions(o);
8
+ const processId = o.processId;
9
+ if (processId === undefined) {
10
+ // TODO: Spawn ANT process, register it to ANT registry, get process ID
11
+ throw new Error('Process ID must be provided for buy-record');
12
+ }
13
+ if (!o.skipConfirmation) {
14
+ const existingRecord = await ario.getArNSRecord({
15
+ name,
16
+ });
17
+ if (existingRecord !== undefined) {
18
+ throw new Error(`ArNS Record ${name} is already owned`);
19
+ }
20
+ await assertEnoughBalanceForArNSPurchase({
21
+ ario,
22
+ address: signerAddress,
23
+ costDetailsParams: {
24
+ intent: 'Buy-Record',
25
+ type,
26
+ name,
27
+ years,
28
+ fundFrom,
29
+ fromAddress: signerAddress,
30
+ },
31
+ });
32
+ await assertConfirmationPrompt(`Are you sure you want to ${type} the record ${name}?`, o);
33
+ }
34
+ return ario.buyRecord({
35
+ name: requiredStringFromOptions(o, 'name'),
36
+ processId,
37
+ type,
38
+ years,
39
+ fundFrom: fundFromFromOptions(o),
40
+ }, writeActionTagsFromOptions(o));
41
+ }
42
+ export async function upgradeRecordCLICommand(o) {
43
+ const name = requiredStringFromOptions(o, 'name');
44
+ const { ario, signerAddress } = writeARIOFromOptions(o);
45
+ const fundFrom = fundFromFromOptions(o);
46
+ if (!o.skipConfirmation) {
47
+ const existingRecord = await ario.getArNSRecord({
48
+ name,
49
+ });
50
+ if (existingRecord === undefined) {
51
+ throw new Error(`ArNS Record ${name} does not exist`);
52
+ }
53
+ if (existingRecord.type === 'permabuy') {
54
+ throw new Error(`ArNS Record ${name} is already a permabuy`);
55
+ }
56
+ await assertEnoughBalanceForArNSPurchase({
57
+ ario,
58
+ address: signerAddress,
59
+ costDetailsParams: {
60
+ intent: 'Upgrade-Name',
61
+ name,
62
+ fundFrom,
63
+ fromAddress: signerAddress,
64
+ },
65
+ });
66
+ await assertConfirmationPrompt(`Are you sure you want to upgrade the lease of ${name} to a permabuy?`, o);
67
+ }
68
+ return ario.upgradeRecord({
69
+ name,
70
+ fundFrom,
71
+ });
72
+ }
73
+ export async function extendLeaseCLICommand(o) {
74
+ const name = requiredStringFromOptions(o, 'name');
75
+ const years = requiredPositiveIntegerFromOptions(o, 'years');
76
+ const fundFrom = fundFromFromOptions(o);
77
+ const { ario, signerAddress } = writeARIOFromOptions(o);
78
+ if (!o.skipConfirmation) {
79
+ const existingRecord = await ario.getArNSRecord({
80
+ name,
81
+ });
82
+ if (existingRecord === undefined) {
83
+ throw new Error(`ArNS Record ${name} does not exist`);
84
+ }
85
+ if (existingRecord.type === 'permabuy') {
86
+ throw new Error(`ArNS Record ${name} is a permabuy and cannot be extended`);
87
+ }
88
+ await assertEnoughBalanceForArNSPurchase({
89
+ ario: ario,
90
+ address: signerAddress,
91
+ costDetailsParams: {
92
+ intent: 'Extend-Lease',
93
+ name,
94
+ years,
95
+ fundFrom,
96
+ fromAddress: signerAddress,
97
+ },
98
+ });
99
+ await assertConfirmationPrompt(`Are you sure you want to extend the lease of ${name} by ${years}?`, o);
100
+ }
101
+ return ario.extendLease({
102
+ name,
103
+ years,
104
+ }, writeActionTagsFromOptions(o));
105
+ }
106
+ export async function increaseUndernameLimitCLICommand(o) {
107
+ const name = requiredStringFromOptions(o, 'name');
108
+ const increaseCount = requiredPositiveIntegerFromOptions(o, 'increaseCount');
109
+ const fundFrom = fundFromFromOptions(o);
110
+ const { ario, signerAddress } = writeARIOFromOptions(o);
111
+ if (!o.skipConfirmation) {
112
+ const existingRecord = await ario.getArNSRecord({
113
+ name,
114
+ });
115
+ if (existingRecord === undefined) {
116
+ throw new Error(`ArNS Record ${name} does not exist`);
117
+ }
118
+ await assertEnoughBalanceForArNSPurchase({
119
+ ario,
120
+ address: signerAddress,
121
+ costDetailsParams: {
122
+ intent: 'Increase-Undername-Limit',
123
+ name,
124
+ quantity: increaseCount,
125
+ fundFrom,
126
+ fromAddress: signerAddress,
127
+ },
128
+ });
129
+ await assertConfirmationPrompt(`Are you sure you want to increase the undername limit of ${name} by ${increaseCount}?`, o);
130
+ }
131
+ return ario.increaseUndernameLimit({
132
+ name,
133
+ increaseCount,
134
+ }, writeActionTagsFromOptions(o));
135
+ }
136
+ export async function requestPrimaryNameCLICommand(o) {
137
+ const { ario, signerAddress } = writeARIOFromOptions(o);
138
+ const fundFrom = fundFromFromOptions(o);
139
+ const name = requiredStringFromOptions(o, 'name');
140
+ if (!o.skipConfirmation) {
141
+ // TODO: Assert name requested is not already owned?
142
+ // TODO: More assertions?
143
+ await assertEnoughBalanceForArNSPurchase({
144
+ ario,
145
+ address: signerAddress,
146
+ costDetailsParams: {
147
+ intent: 'Primary-Name-Request',
148
+ name,
149
+ fromAddress: signerAddress,
150
+ fundFrom,
151
+ },
152
+ });
153
+ await assertConfirmationPrompt(`Are you sure you want to request the primary name ${name}?`, o);
154
+ }
155
+ return ario.requestPrimaryName({
156
+ name,
157
+ fundFrom,
158
+ }, writeActionTagsFromOptions(o));
159
+ }
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import prompts from 'prompts';
17
17
  import { mARIOToken } from '../../node/index.js';
18
- import { assertConfirmationPrompt, assertEnoughBalance, formatARIOWithCommas, gatewaySettingsFromOptions, redelegateParamsFromOptions, requiredAddressFromOptions, requiredMIOFromOptions as requiredMARIOFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, requiredTargetAndQuantityFromOptions, stringifyJsonForCLIDisplay, writeARIOFromOptions, writeActionTagsFromOptions, } from '../utils.js';
18
+ import { assertConfirmationPrompt, assertEnoughMARIOBalance, formatARIOWithCommas, gatewaySettingsFromOptions, redelegateParamsFromOptions, requiredAddressFromOptions, requiredMARIOFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, requiredTargetAndQuantityFromOptions, stringifyJsonForCLIDisplay, writeARIOFromOptions, writeActionTagsFromOptions, } from '../utils.js';
19
19
  export async function joinNetwork(options) {
20
20
  const { ario, signerAddress } = writeARIOFromOptions(options);
21
21
  const mARIOQuantity = requiredMARIOFromOptions(options, 'operatorStake');
@@ -34,7 +34,11 @@ export async function joinNetwork(options) {
34
34
  if (settings.operators.minStake > mARIOQuantity.valueOf()) {
35
35
  throw new Error(`The minimum operator stake is ${formatARIOWithCommas(new mARIOToken(settings.operators.minStake).toARIO())} ARIO. Please provide a higher stake.`);
36
36
  }
37
- await assertEnoughBalance(ario, signerAddress, mARIOQuantity.toARIO());
37
+ await assertEnoughMARIOBalance({
38
+ ario,
39
+ address: signerAddress,
40
+ mARIOQuantity,
41
+ });
38
42
  await assertConfirmationPrompt(`Gateway Settings:\n\n${JSON.stringify(settings, null, 2)}\n\nYou are about to stake ${formatARIOWithCommas(mARIOQuantity.toARIO())} ARIO to join the AR.IO network\nAre you sure?\n`, options);
39
43
  }
40
44
  const result = await ario.joinNetwork(settings, writeActionTagsFromOptions(options));
@@ -1,21 +1,5 @@
1
- /**
2
- * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { fundFromOptions, isValidFundFrom, } from '../../types/io.js';
17
1
  import { mARIOToken } from '../../types/token.js';
18
- import { addressFromOptions, epochInputFromOptions, formatARIOWithCommas, getTokenCostParamsFromOptions, paginationParamsFromOptions, readARIOFromOptions, requiredAddressFromOptions, requiredStringFromOptions, } from '../utils.js';
2
+ import { addressFromOptions, epochInputFromOptions, formatARIOWithCommas, fundFromFromOptions, getTokenCostParamsFromOptions, paginationParamsFromOptions, readARIOFromOptions, requiredAddressFromOptions, requiredStringFromOptions, } from '../utils.js';
19
3
  export async function getGateway(o) {
20
4
  const address = requiredAddressFromOptions(o);
21
5
  const gateway = await readARIOFromOptions(o).getGateway({
@@ -123,14 +107,9 @@ export async function getTokenCost(o) {
123
107
  return output;
124
108
  }
125
109
  export async function getCostDetails(o) {
126
- if (o.fundFrom !== undefined) {
127
- if (!isValidFundFrom(o.fundFrom)) {
128
- throw new Error(`Invalid fund from: ${o.fundFrom}. Please use one of ${fundFromOptions.join(', ')}`);
129
- }
130
- }
131
110
  const costDetails = await readARIOFromOptions(o).getCostDetails({
132
111
  ...getTokenCostParamsFromOptions(o),
133
- fundFrom: o.fundFrom,
112
+ fundFrom: fundFromFromOptions(o),
134
113
  });
135
114
  const output = {
136
115
  ...costDetails,
@@ -1,9 +1,13 @@
1
- import { assertEnoughBalance, confirmationPrompt, formatARIOWithCommas, requiredTargetAndQuantityFromOptions, writeARIOFromOptions, writeActionTagsFromOptions, } from '../utils.js';
1
+ import { assertEnoughMARIOBalance, confirmationPrompt, formatARIOWithCommas, requiredTargetAndQuantityFromOptions, writeARIOFromOptions, writeActionTagsFromOptions, } from '../utils.js';
2
2
  export async function transfer(options) {
3
3
  const { target, arioQuantity } = requiredTargetAndQuantityFromOptions(options);
4
4
  const { ario, signerAddress } = writeARIOFromOptions(options);
5
5
  if (!options.skipConfirmation) {
6
- await assertEnoughBalance(ario, signerAddress, arioQuantity);
6
+ await assertEnoughMARIOBalance({
7
+ ario,
8
+ address: signerAddress,
9
+ mARIOQuantity: arioQuantity.toMARIO(),
10
+ });
7
11
  const confirm = await confirmationPrompt(`Are you sure you want to transfer ${formatARIOWithCommas(arioQuantity)} ARIO to ${target}?`);
8
12
  if (!confirm) {
9
13
  return { message: 'Transfer aborted by user' };
@@ -252,11 +252,13 @@ export const globalOptions = [
252
252
  optionMap.cuUrl,
253
253
  ];
254
254
  export const writeActionOptions = [optionMap.skipConfirmation, optionMap.tags];
255
- export const addressOptions = [optionMap.address];
256
- export const nameOptions = [optionMap.name];
257
- export const initiatorOptions = [optionMap.initiator];
255
+ export const arnsPurchaseOptions = [
256
+ ...writeActionOptions,
257
+ optionMap.name,
258
+ optionMap.fundFrom,
259
+ ];
258
260
  export const epochOptions = [optionMap.epochIndex, optionMap.timestamp];
259
- export const addressAndVaultIdOptions = [...addressOptions, optionMap.vaultId];
261
+ export const addressAndVaultIdOptions = [optionMap.address, optionMap.vaultId];
260
262
  export const nameWriteOptions = [...writeActionOptions, optionMap.name];
261
263
  export const paginationOptions = [
262
264
  optionMap.cursor,
@@ -313,8 +315,7 @@ export const joinNetworkOptions = [
313
315
  optionMap.operatorStake,
314
316
  ];
315
317
  export const buyRecordOptions = [
316
- ...writeActionOptions,
317
- optionMap.name,
318
+ ...arnsPurchaseOptions,
318
319
  optionMap.quantity,
319
320
  optionMap.type,
320
321
  optionMap.years,
@@ -17,7 +17,7 @@ import { connect } from '@permaweb/aoconnect';
17
17
  import { program } from 'commander';
18
18
  import { readFileSync } from 'fs';
19
19
  import prompts from 'prompts';
20
- import { ANT, AOProcess, ARIO, ARIOToken, ARIO_DEVNET_PROCESS_ID, ARIO_TESTNET_PROCESS_ID, ArweaveSigner, Logger, createAoSigner, fromB64Url, initANTStateForAddress, isValidIntent, mARIOToken, sha256B64Url, validIntents, } from '../node/index.js';
20
+ import { ANT, AOProcess, ARIO, ARIOToken, ARIO_DEVNET_PROCESS_ID, ARIO_TESTNET_PROCESS_ID, ArweaveSigner, Logger, createAoSigner, fromB64Url, fundFromOptions, initANTStateForAddress, isValidFundFrom, isValidIntent, mARIOToken, sha256B64Url, validIntents, } from '../node/index.js';
21
21
  import { globalOptions } from './options.js';
22
22
  export function stringifyJsonForCLIDisplay(json) {
23
23
  return JSON.stringify(json, null, 2);
@@ -141,6 +141,9 @@ export function formatARIOWithCommas(value) {
141
141
  }
142
142
  return integerWithCommas + '.' + decimalPart;
143
143
  }
144
+ export function formatMARIOToARIOWithCommas(value) {
145
+ return formatARIOWithCommas(value.toARIO());
146
+ }
144
147
  /** helper to get address from --address option first, then check wallet options */
145
148
  export function addressFromOptions(options) {
146
149
  if (options.address !== undefined) {
@@ -265,16 +268,34 @@ export function recordTypeFromOptions(options) {
265
268
  }
266
269
  return options.type;
267
270
  }
268
- export function requiredMIOFromOptions(options, key) {
271
+ export function requiredMARIOFromOptions(options, key) {
269
272
  if (options[key] === undefined) {
270
273
  throw new Error(`No ${key} provided. Use --${key} denominated in ARIO`);
271
274
  }
272
275
  return new ARIOToken(+options[key]).toMARIO();
273
276
  }
274
- export async function assertEnoughBalance(ario, address, arioQuantity) {
277
+ export async function assertEnoughBalanceForArNSPurchase({ ario, address, costDetailsParams, }) {
278
+ const costDetails = await ario.getCostDetails(costDetailsParams);
279
+ if (costDetails.fundingPlan) {
280
+ if (costDetails.fundingPlan.shortfall > 0) {
281
+ throw new Error(`Insufficient balance for action. Shortfall: ${formatMARIOToARIOWithCommas(new mARIOToken(costDetails.fundingPlan.shortfall))}\n${JSON.stringify(costDetails, null, 2)}`);
282
+ }
283
+ }
284
+ else {
285
+ await assertEnoughMARIOBalance({
286
+ ario,
287
+ address,
288
+ mARIOQuantity: costDetails.tokenCost,
289
+ });
290
+ }
291
+ }
292
+ export async function assertEnoughMARIOBalance({ address, ario, mARIOQuantity, }) {
293
+ if (typeof mARIOQuantity === 'number') {
294
+ mARIOQuantity = new mARIOToken(mARIOQuantity);
295
+ }
275
296
  const balance = await ario.getBalance({ address });
276
- if (balance < arioQuantity.toMARIO().valueOf()) {
277
- throw new Error(`Insufficient ARIO balance for action. Balance available: ${new mARIOToken(balance).toARIO()} ARIO`);
297
+ if (balance < mARIOQuantity.valueOf()) {
298
+ throw new Error(`Insufficient ARIO balance for action. Balance available: ${formatMARIOToARIOWithCommas(new mARIOToken(balance))} ARIO`);
278
299
  }
279
300
  }
280
301
  export async function confirmationPrompt(message) {
@@ -383,3 +404,11 @@ export function getTokenCostParamsFromOptions(o) {
383
404
  fromAddress: addressFromOptions(o),
384
405
  };
385
406
  }
407
+ export function fundFromFromOptions(o) {
408
+ if (o.fundFrom !== undefined) {
409
+ if (!isValidFundFrom(o.fundFrom)) {
410
+ throw new Error(`Invalid fund from: ${o.fundFrom}. Please use one of ${fundFromOptions.join(', ')}`);
411
+ }
412
+ }
413
+ return o.fundFrom ?? 'balance';
414
+ }
@@ -708,6 +708,7 @@ export class ARIOWriteable extends ARIOReadable {
708
708
  { name: 'Years', value: params.years?.toString() ?? '1' },
709
709
  { name: 'Process-Id', value: params.processId },
710
710
  { name: 'Purchase-Type', value: params.type || 'lease' },
711
+ { name: 'Fund-From', value: params.fundFrom },
711
712
  ];
712
713
  return this.process.send({
713
714
  signer: this.signer,
@@ -724,13 +725,15 @@ export class ARIOWriteable extends ARIOReadable {
724
725
  */
725
726
  async upgradeRecord(params, options) {
726
727
  const { tags = [] } = options || {};
728
+ const allTags = [
729
+ ...tags,
730
+ { name: 'Action', value: 'Upgrade-Name' }, // TODO: align on Update-Record vs. Upgrade-Name (contract currently uses Upgrade-Name)
731
+ { name: 'Name', value: params.name },
732
+ { name: 'Fund-From', value: params.fundFrom },
733
+ ];
727
734
  return this.process.send({
728
735
  signer: this.signer,
729
- tags: [
730
- ...tags,
731
- { name: 'Action', value: 'Upgrade-Name' }, // TODO: align on Update-Record vs. Upgrade-Name (contract currently uses Upgrade-Name)
732
- { name: 'Name', value: params.name },
733
- ],
736
+ tags: pruneTags(allTags),
734
737
  });
735
738
  }
736
739
  /**
@@ -744,26 +747,30 @@ export class ARIOWriteable extends ARIOReadable {
744
747
  */
745
748
  async extendLease(params, options) {
746
749
  const { tags = [] } = options || {};
750
+ const allTags = [
751
+ ...tags,
752
+ { name: 'Action', value: 'Extend-Lease' },
753
+ { name: 'Name', value: params.name },
754
+ { name: 'Years', value: params.years.toString() },
755
+ { name: 'Fund-From', value: params.fundFrom },
756
+ ];
747
757
  return this.process.send({
748
758
  signer: this.signer,
749
- tags: [
750
- ...tags,
751
- { name: 'Action', value: 'Extend-Lease' },
752
- { name: 'Name', value: params.name },
753
- { name: 'Years', value: params.years.toString() },
754
- ],
759
+ tags: pruneTags(allTags),
755
760
  });
756
761
  }
757
762
  async increaseUndernameLimit(params, options) {
758
763
  const { tags = [] } = options || {};
764
+ const allTags = [
765
+ ...tags,
766
+ { name: 'Action', value: 'Increase-Undername-Limit' },
767
+ { name: 'Name', value: params.name },
768
+ { name: 'Quantity', value: params.increaseCount.toString() },
769
+ { name: 'Fund-From', value: params.fundFrom },
770
+ ];
759
771
  return this.process.send({
760
772
  signer: this.signer,
761
- tags: [
762
- ...tags,
763
- { name: 'Action', value: 'Increase-Undername-Limit' },
764
- { name: 'Name', value: params.name },
765
- { name: 'Quantity', value: params.increaseCount.toString() },
766
- ],
773
+ tags: pruneTags(allTags),
767
774
  });
768
775
  }
769
776
  /**
@@ -788,13 +795,16 @@ export class ARIOWriteable extends ARIOReadable {
788
795
  tags: pruneTags(allTags),
789
796
  });
790
797
  }
791
- async requestPrimaryName(params) {
798
+ async requestPrimaryName(params, options) {
799
+ const { tags = [] } = options || {};
800
+ const allTags = [
801
+ ...tags,
802
+ { name: 'Action', value: 'Request-Primary-Name' },
803
+ { name: 'Name', value: params.name },
804
+ ];
792
805
  return this.process.send({
793
806
  signer: this.signer,
794
- tags: [
795
- { name: 'Action', value: 'Request-Primary-Name' },
796
- { name: 'Name', value: params.name },
797
- ],
807
+ tags: pruneTags(allTags),
798
808
  });
799
809
  }
800
810
  /**
@@ -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.1.0-alpha.1';
17
+ export const version = '3.1.0-alpha.2';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { AoArNSPurchaseParams, AoBuyRecordParams, AoExtendLeaseParams, AoIncreaseUndernameLimitParams } from '../../types/io.js';
17
+ import { CLIWriteOptionsFromAoParams } from '../types.js';
18
+ export declare function buyRecordCLICommand(o: CLIWriteOptionsFromAoParams<AoBuyRecordParams>): Promise<import("../../types/common.js").AoMessageResult>;
19
+ export declare function upgradeRecordCLICommand(o: CLIWriteOptionsFromAoParams<AoArNSPurchaseParams>): Promise<import("../../types/common.js").AoMessageResult>;
20
+ export declare function extendLeaseCLICommand(o: CLIWriteOptionsFromAoParams<AoExtendLeaseParams>): Promise<import("../../types/common.js").AoMessageResult>;
21
+ export declare function increaseUndernameLimitCLICommand(o: CLIWriteOptionsFromAoParams<AoIncreaseUndernameLimitParams>): Promise<import("../../types/common.js").AoMessageResult>;
22
+ export declare function requestPrimaryNameCLICommand(o: CLIWriteOptionsFromAoParams<AoArNSPurchaseParams>): Promise<import("../../types/common.js").AoMessageResult>;
@@ -248,15 +248,7 @@ export declare const writeActionOptions: {
248
248
  description: string;
249
249
  type: string;
250
250
  }[];
251
- export declare const addressOptions: {
252
- alias: string;
253
- description: string;
254
- }[];
255
- export declare const nameOptions: {
256
- alias: string;
257
- description: string;
258
- }[];
259
- export declare const initiatorOptions: {
251
+ export declare const arnsPurchaseOptions: {
260
252
  alias: string;
261
253
  description: string;
262
254
  }[];