@ar.io/sdk 2.6.0 → 2.7.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.
Files changed (37) hide show
  1. package/bundles/web.bundle.min.js +65 -65
  2. package/lib/cjs/cli/cli.js +712 -0
  3. package/lib/cjs/cli/commands/gatewayWriteCommands.js +211 -0
  4. package/lib/cjs/cli/commands/readCommands.js +219 -0
  5. package/lib/cjs/cli/commands/transfer.js +26 -0
  6. package/lib/cjs/cli/options.js +336 -0
  7. package/lib/cjs/cli/types.js +2 -0
  8. package/lib/cjs/cli/utils.js +406 -0
  9. package/lib/cjs/common/io.js +2 -7
  10. package/lib/cjs/types/io.js +13 -1
  11. package/lib/cjs/utils/ao.js +32 -13
  12. package/lib/cjs/utils/base64.js +1 -1
  13. package/lib/cjs/version.js +1 -1
  14. package/lib/esm/cli/cli.js +710 -0
  15. package/lib/esm/cli/commands/gatewayWriteCommands.js +194 -0
  16. package/lib/esm/cli/commands/readCommands.js +197 -0
  17. package/lib/esm/cli/commands/transfer.js +22 -0
  18. package/lib/esm/cli/options.js +333 -0
  19. package/lib/esm/cli/types.js +1 -0
  20. package/lib/esm/cli/utils.js +366 -0
  21. package/lib/esm/common/io.js +2 -7
  22. package/lib/esm/types/io.js +11 -0
  23. package/lib/esm/utils/ao.js +30 -12
  24. package/lib/esm/utils/base64.js +1 -1
  25. package/lib/esm/version.js +1 -1
  26. package/lib/types/cli/cli.d.ts +2 -0
  27. package/lib/types/cli/commands/gatewayWriteCommands.d.ts +38 -0
  28. package/lib/types/cli/commands/readCommands.d.ts +57 -0
  29. package/lib/types/cli/commands/transfer.d.ts +23 -0
  30. package/lib/types/cli/options.d.ts +326 -0
  31. package/lib/types/cli/types.d.ts +106 -0
  32. package/lib/types/cli/utils.d.ts +66 -0
  33. package/lib/types/common/io.d.ts +4 -7
  34. package/lib/types/types/io.d.ts +81 -60
  35. package/lib/types/utils/ao.d.ts +20 -10
  36. package/lib/types/version.d.ts +1 -1
  37. package/package.json +7 -1
@@ -0,0 +1,333 @@
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
+ export const optionMap = {
17
+ walletFile: {
18
+ alias: '-w, --wallet-file <walletFilePath>',
19
+ description: 'The file path to the wallet to use for the interaction',
20
+ },
21
+ // mnemonic: {
22
+ // alias: '-m, --mnemonic <phrase>',
23
+ // description: 'Mnemonic to use with the action',
24
+ // },
25
+ privateKey: {
26
+ alias: '--private-key <key>',
27
+ description: 'Private key to use with the action',
28
+ },
29
+ dev: {
30
+ alias: '--dev',
31
+ description: 'Run against the AR.IO devnet process',
32
+ type: 'boolean',
33
+ },
34
+ ioProcessId: {
35
+ alias: '--io-process-id',
36
+ description: 'Run against a custom AR.IO process id',
37
+ },
38
+ cuUrl: {
39
+ alias: '--cu-url <cuUrl>',
40
+ description: 'The URL for a custom compute unit',
41
+ },
42
+ processId: {
43
+ alias: '--process-id <processId>',
44
+ description: 'The process ID to interact with',
45
+ },
46
+ debug: {
47
+ alias: '--debug',
48
+ description: 'Enable debug log output',
49
+ type: 'boolean',
50
+ },
51
+ address: {
52
+ alias: '-a, --address <address>',
53
+ description: 'The address to interact with',
54
+ },
55
+ target: {
56
+ alias: '--target <target>',
57
+ description: 'The target address to interact with',
58
+ },
59
+ source: {
60
+ alias: '--source <source>',
61
+ description: 'The source address to interact with',
62
+ },
63
+ quantity: {
64
+ alias: '-q, --quantity <quantity>',
65
+ description: 'The quantity of IO to interact with',
66
+ },
67
+ autoStake: {
68
+ alias: '--auto-stake',
69
+ description: 'Enable auto-staking of operator rewards',
70
+ type: 'boolean',
71
+ },
72
+ allowDelegatedStaking: {
73
+ alias: '--allow-delegated-staking',
74
+ description: 'Allow delegating stake to the gateway',
75
+ type: 'boolean',
76
+ },
77
+ minDelegatedStake: {
78
+ alias: '--min-delegated-stake <minDelegatedStake>',
79
+ description: 'The minimum delegated stake allowed',
80
+ },
81
+ delegateRewardShareRatio: {
82
+ alias: '--delegate-reward-share-ratio <delegateRewardShareRatio>',
83
+ description: 'The percentage of rewards to share with delegates',
84
+ },
85
+ label: {
86
+ alias: '--label <label>',
87
+ description: 'The label for the gateway',
88
+ },
89
+ note: {
90
+ alias: '--note <note>',
91
+ description: 'The note for the gateway',
92
+ },
93
+ properties: {
94
+ alias: '--properties <properties>',
95
+ description: 'The properties for the gateway',
96
+ },
97
+ observerAddress: {
98
+ alias: '--observer-address <observerAddress>',
99
+ description: 'The observer wallet address for the gateway',
100
+ },
101
+ fqdn: {
102
+ alias: '--fqdn <fqdn>',
103
+ description: 'The fully qualified domain name for the gateway',
104
+ },
105
+ port: {
106
+ alias: '--port <port>',
107
+ description: 'The port for the gateway',
108
+ },
109
+ protocol: {
110
+ alias: '--protocol <protocol>',
111
+ description: 'The protocol for the gateway',
112
+ },
113
+ allowedDelegates: {
114
+ alias: '--allowed-delegates <allowedDelegates...>',
115
+ description: 'The allowed delegates for the gateway. By default this is empty, meaning all are allowed delegate stake unless delegating is explicitly disallowed by the gateway',
116
+ type: 'array',
117
+ },
118
+ skipConfirmation: {
119
+ alias: '--skip-confirmation',
120
+ description: 'Skip confirmation prompts',
121
+ type: 'boolean',
122
+ },
123
+ vaultId: {
124
+ alias: '--vault-id <vaultId>',
125
+ description: 'The vault ID to interact with',
126
+ },
127
+ operatorStake: {
128
+ alias: '--operator-stake <operatorStake>',
129
+ description: 'The operator stake to interact with',
130
+ },
131
+ name: {
132
+ alias: '--name <name>',
133
+ description: 'The ArNS name to interact with',
134
+ },
135
+ epochIndex: {
136
+ alias: '--epoch-index <epochIndex>',
137
+ description: 'The epoch index to interact with',
138
+ },
139
+ timestamp: {
140
+ alias: '--timestamp <timestamp>',
141
+ description: 'The timestamp to interact with',
142
+ },
143
+ initiator: {
144
+ alias: '--initiator <initiator>',
145
+ description: 'The initiator of the action',
146
+ },
147
+ intent: {
148
+ alias: '--intent <intent>',
149
+ description: 'The intent for the cost details action',
150
+ },
151
+ type: {
152
+ alias: '--type <type>',
153
+ description: 'The type for the cost details action. Either "lease" or "permabuy"',
154
+ },
155
+ years: {
156
+ alias: '--years <years>',
157
+ description: 'The number of years for the cost details action',
158
+ },
159
+ intervalMs: {
160
+ alias: '--interval-ms <intervalMs>',
161
+ description: 'The interval in milliseconds for the action',
162
+ },
163
+ cursor: {
164
+ alias: '--cursor <cursor>',
165
+ description: 'The cursor for pagination',
166
+ },
167
+ limit: {
168
+ alias: '--limit <limit>',
169
+ description: 'The limit for pagination',
170
+ },
171
+ sortBy: {
172
+ alias: '--sort-by <sortBy>',
173
+ description: 'The field to sort by',
174
+ },
175
+ sortOrder: {
176
+ alias: '--sort-order <sortOrder>',
177
+ description: 'The order to sort by, either "asc" or "desc"',
178
+ },
179
+ tags: {
180
+ description: 'An array of additional tags for the write action, in "--tags name1 value1 name2 value2" format',
181
+ alias: '--tags <tags...>',
182
+ type: 'array',
183
+ },
184
+ instant: {
185
+ alias: '--instant',
186
+ description: 'Use the instant transaction method',
187
+ type: 'boolean',
188
+ },
189
+ increaseCount: {
190
+ alias: '--increase-count <increaseCount>',
191
+ description: 'Amount to increase the undername count of the record by',
192
+ },
193
+ undername: {
194
+ alias: '--undername <undername>',
195
+ description: 'The undername to interact with',
196
+ },
197
+ controller: {
198
+ alias: '--controller <controller>',
199
+ description: 'The controller to interact with',
200
+ },
201
+ controllers: {
202
+ alias: '--controllers <controllers...>',
203
+ description: 'The controller to interact with',
204
+ type: 'array',
205
+ },
206
+ transactionId: {
207
+ alias: '--transaction-id <transactionId>',
208
+ description: 'The transaction ID to interact with',
209
+ },
210
+ ttlSeconds: {
211
+ alias: '--ttl-seconds <ttlSeconds>',
212
+ description: 'The TTL in seconds for the record',
213
+ },
214
+ ticker: {
215
+ alias: '--ticker <ticker>',
216
+ description: 'The ticker for the ANT',
217
+ },
218
+ description: {
219
+ alias: '--description <description>',
220
+ description: 'The description for the ANT',
221
+ },
222
+ keywords: {
223
+ alias: '--keywords <keywords...>',
224
+ description: 'The keywords for the ANT',
225
+ type: 'array',
226
+ },
227
+ names: {
228
+ alias: '--names <names...>',
229
+ description: 'The names to interact with',
230
+ type: 'array',
231
+ },
232
+ failedGateways: {
233
+ alias: '--failed-gateways <failedGateways...>',
234
+ description: 'Include failed gateways in the list',
235
+ type: 'array',
236
+ },
237
+ };
238
+ export const walletOptions = [
239
+ optionMap.walletFile,
240
+ // optionMap.mnemonic,
241
+ optionMap.privateKey,
242
+ ];
243
+ export const globalOptions = [
244
+ ...walletOptions,
245
+ optionMap.dev,
246
+ optionMap.debug,
247
+ optionMap.ioProcessId,
248
+ optionMap.cuUrl,
249
+ ];
250
+ export const writeActionOptions = [optionMap.skipConfirmation, optionMap.tags];
251
+ export const addressOptions = [optionMap.address];
252
+ export const nameOptions = [optionMap.name];
253
+ export const initiatorOptions = [optionMap.initiator];
254
+ export const epochOptions = [optionMap.epochIndex, optionMap.timestamp];
255
+ export const addressAndVaultIdOptions = [...addressOptions, optionMap.vaultId];
256
+ export const nameWriteOptions = [...writeActionOptions, optionMap.name];
257
+ export const paginationOptions = [
258
+ optionMap.cursor,
259
+ optionMap.limit,
260
+ optionMap.sortBy,
261
+ optionMap.sortOrder,
262
+ ];
263
+ export const paginationAddressOptions = [
264
+ optionMap.address,
265
+ ...paginationOptions,
266
+ ];
267
+ export const getVaultOptions = addressAndVaultIdOptions;
268
+ export const tokenCostOptions = [
269
+ optionMap.name,
270
+ optionMap.intent,
271
+ optionMap.type,
272
+ optionMap.years,
273
+ optionMap.quantity,
274
+ ];
275
+ export const arNSAuctionPricesOptions = [
276
+ optionMap.name,
277
+ optionMap.type,
278
+ optionMap.years,
279
+ optionMap.timestamp,
280
+ optionMap.intervalMs,
281
+ ];
282
+ export const transferOptions = [
283
+ ...writeActionOptions,
284
+ optionMap.quantity,
285
+ optionMap.target,
286
+ ];
287
+ export const operatorStakeOptions = [
288
+ ...writeActionOptions,
289
+ optionMap.operatorStake,
290
+ ];
291
+ export const redelegateStakeOptions = [...transferOptions, optionMap.source];
292
+ export const delegateStakeOptions = transferOptions;
293
+ export const decreaseDelegateStakeOptions = [
294
+ ...delegateStakeOptions,
295
+ optionMap.instant,
296
+ ];
297
+ export const updateGatewaySettingsOptions = [
298
+ ...writeActionOptions,
299
+ optionMap.autoStake,
300
+ optionMap.allowDelegatedStaking,
301
+ optionMap.allowedDelegates,
302
+ optionMap.minDelegatedStake,
303
+ optionMap.delegateRewardShareRatio,
304
+ optionMap.label,
305
+ optionMap.note,
306
+ optionMap.properties,
307
+ optionMap.observerAddress,
308
+ optionMap.fqdn,
309
+ optionMap.port,
310
+ optionMap.protocol,
311
+ ];
312
+ export const joinNetworkOptions = [
313
+ ...updateGatewaySettingsOptions,
314
+ optionMap.operatorStake,
315
+ ];
316
+ export const buyRecordOptions = [
317
+ ...writeActionOptions,
318
+ optionMap.name,
319
+ optionMap.quantity,
320
+ optionMap.type,
321
+ optionMap.years,
322
+ optionMap.processId,
323
+ ];
324
+ export const antStateOptions = [
325
+ ...writeActionOptions,
326
+ optionMap.target,
327
+ optionMap.keywords,
328
+ optionMap.ticker,
329
+ optionMap.name,
330
+ optionMap.description,
331
+ optionMap.controllers,
332
+ optionMap.ttlSeconds,
333
+ ];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,366 @@
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 { connect } from '@permaweb/aoconnect';
17
+ import { program } from 'commander';
18
+ import { readFileSync } from 'fs';
19
+ import prompts from 'prompts';
20
+ import { ANT, AOProcess, ArweaveSigner, IO, IOToken, IO_DEVNET_PROCESS_ID, IO_TESTNET_PROCESS_ID, Logger, createAoSigner, fromB64Url, initANTStateForAddress, mIOToken, sha256B64Url, } from '../node/index.js';
21
+ import { globalOptions } from './options.js';
22
+ export function stringifyJsonForCLIDisplay(json) {
23
+ return JSON.stringify(json, null, 2);
24
+ }
25
+ function logCommandOutput(output) {
26
+ console.log(stringifyJsonForCLIDisplay(output));
27
+ }
28
+ function exitWithErrorLog(error, debug = false) {
29
+ let errorLog;
30
+ if (error instanceof Error) {
31
+ errorLog = error.message;
32
+ if (debug && error.stack !== undefined) {
33
+ errorLog = error.stack;
34
+ }
35
+ }
36
+ else {
37
+ errorLog = stringifyJsonForCLIDisplay(error);
38
+ }
39
+ console.error(errorLog);
40
+ process.exit(1);
41
+ }
42
+ export async function runCommand(command, action) {
43
+ const options = command.optsWithGlobals();
44
+ try {
45
+ const output = await action(options);
46
+ logCommandOutput(output);
47
+ process.exit(0);
48
+ }
49
+ catch (error) {
50
+ exitWithErrorLog(error, options.debug);
51
+ }
52
+ }
53
+ function applyOptions(command, options) {
54
+ [...options].forEach((option) => {
55
+ command.option(option.alias, option.description, option.default);
56
+ });
57
+ return command;
58
+ }
59
+ export function makeCommand({ description, name, options = [], action, }) {
60
+ const command = program.command(name).description(description);
61
+ const appliedCommand = applyOptions(command, [...options, ...globalOptions]);
62
+ if (action !== undefined) {
63
+ appliedCommand.action(() => runCommand(appliedCommand, action));
64
+ }
65
+ return appliedCommand;
66
+ }
67
+ export function ioProcessIdFromOptions({ ioProcessId, dev, }) {
68
+ return ioProcessId !== undefined
69
+ ? ioProcessId
70
+ : dev
71
+ ? IO_DEVNET_PROCESS_ID
72
+ : IO_TESTNET_PROCESS_ID;
73
+ }
74
+ function jwkFromOptions({ privateKey, walletFile, }) {
75
+ if (privateKey !== undefined) {
76
+ return JSON.parse(privateKey);
77
+ }
78
+ if (walletFile !== undefined) {
79
+ return JSON.parse(readFileSync(walletFile, 'utf-8'));
80
+ }
81
+ return undefined;
82
+ }
83
+ export function requiredJwkFromOptions(options) {
84
+ const jwk = jwkFromOptions(options);
85
+ if (jwk === undefined) {
86
+ throw new Error('No JWK provided for signing!\nPlease provide a stringified JWK with `--private-key` or the file path of a jwk.json file with `--wallet-file`');
87
+ }
88
+ return jwk;
89
+ }
90
+ export function jwkToAddress(jwk) {
91
+ return sha256B64Url(fromB64Url(jwk.n));
92
+ }
93
+ function setLoggerIfDebug(options) {
94
+ if (options.debug) {
95
+ Logger.default.setLogLevel('debug');
96
+ }
97
+ }
98
+ export function getLoggerFromOptions(options) {
99
+ setLoggerIfDebug(options);
100
+ return Logger.default;
101
+ }
102
+ function aoProcessFromOptions(options) {
103
+ return new AOProcess({
104
+ processId: ioProcessIdFromOptions(options),
105
+ ao: connect({
106
+ CU_URL: options.cuUrl,
107
+ }),
108
+ });
109
+ }
110
+ export function readIOFromOptions(options) {
111
+ setLoggerIfDebug(options);
112
+ return IO.init({
113
+ process: aoProcessFromOptions(options),
114
+ });
115
+ }
116
+ export function requiredContractSignerFromOptions(options) {
117
+ // TODO: Support other wallet types
118
+ const jwk = requiredJwkFromOptions(options);
119
+ const signer = new ArweaveSigner(jwk);
120
+ return { signer, signerAddress: jwkToAddress(jwk) };
121
+ }
122
+ export function requiredAoSignerFromOptions(options) {
123
+ return createAoSigner(requiredContractSignerFromOptions(options).signer);
124
+ }
125
+ export function writeIOFromOptions(options) {
126
+ const { signer, signerAddress } = requiredContractSignerFromOptions(options);
127
+ setLoggerIfDebug(options);
128
+ return {
129
+ io: IO.init({
130
+ process: aoProcessFromOptions(options),
131
+ signer,
132
+ }),
133
+ signerAddress,
134
+ };
135
+ }
136
+ export function formatIOWithCommas(value) {
137
+ const [integerPart, decimalPart] = value.toString().split('.');
138
+ const integerWithCommas = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
139
+ if (decimalPart === undefined) {
140
+ return integerWithCommas;
141
+ }
142
+ return integerWithCommas + '.' + decimalPart;
143
+ }
144
+ /** helper to get address from --address option first, then check wallet options */
145
+ export function addressFromOptions(options) {
146
+ if (options.address !== undefined) {
147
+ return options.address;
148
+ }
149
+ // TODO: Support other wallet types
150
+ const jwk = jwkFromOptions(options);
151
+ if (jwk !== undefined) {
152
+ return jwkToAddress(jwk);
153
+ }
154
+ return undefined;
155
+ }
156
+ export function requiredAddressFromOptions(options) {
157
+ const address = addressFromOptions(options);
158
+ if (address !== undefined) {
159
+ return address;
160
+ }
161
+ throw new Error('No address provided. Use --address or --wallet-file');
162
+ }
163
+ const defaultCliPaginationLimit = 10; // more friendly UX than 100
164
+ export function paginationParamsFromOptions(options) {
165
+ const { cursor, limit, sortBy, sortOrder } = options;
166
+ if (sortOrder !== undefined && !['asc', 'desc'].includes(sortOrder)) {
167
+ throw new Error(`Invalid sort order: ${sortOrder}, must be "asc" or "desc"`);
168
+ }
169
+ const numberLimit = limit !== undefined ? +limit : defaultCliPaginationLimit;
170
+ if (isNaN(numberLimit) || numberLimit <= 0) {
171
+ throw new Error(`Invalid limit: ${numberLimit}, must be a positive number`);
172
+ }
173
+ return {
174
+ cursor,
175
+ limit: numberLimit,
176
+ sortBy,
177
+ sortOrder,
178
+ };
179
+ }
180
+ export function epochInputFromOptions(options) {
181
+ if (options.epochIndex !== undefined) {
182
+ return { epochIndex: +options.epochIndex };
183
+ }
184
+ if (options.timestamp !== undefined) {
185
+ return { timestamp: +options.timestamp };
186
+ }
187
+ return undefined;
188
+ }
189
+ export function requiredInitiatorFromOptions(options) {
190
+ if (options.initiator !== undefined) {
191
+ return options.initiator;
192
+ }
193
+ return requiredAddressFromOptions(options);
194
+ }
195
+ export function writeActionTagsFromOptions(options) {
196
+ if (options.tags === undefined) {
197
+ return {};
198
+ }
199
+ if (!Array.isArray(options.tags)) {
200
+ throw new Error('Tags must be an array');
201
+ }
202
+ if (options.tags.length === 0) {
203
+ return {};
204
+ }
205
+ if (options.tags.length % 2 !== 0) {
206
+ throw new Error('Tags must be an array of key-value pairs');
207
+ }
208
+ const tags = [];
209
+ for (let i = 0; i < options.tags.length; i += 2) {
210
+ tags.push({
211
+ name: options.tags[i],
212
+ value: options.tags[i + 1],
213
+ });
214
+ }
215
+ return {
216
+ tags,
217
+ };
218
+ }
219
+ export function gatewaySettingsFromOptions({ allowDelegatedStaking, autoStake, delegateRewardShareRatio, fqdn, label, minDelegatedStake, note, observerAddress, port, properties, allowedDelegates, }) {
220
+ return {
221
+ observerAddress,
222
+ allowDelegatedStaking,
223
+ autoStake,
224
+ delegateRewardShareRatio: delegateRewardShareRatio !== undefined
225
+ ? +delegateRewardShareRatio
226
+ : undefined,
227
+ allowedDelegates,
228
+ fqdn,
229
+ label,
230
+ minDelegatedStake: minDelegatedStake !== undefined ? +minDelegatedStake : undefined,
231
+ note,
232
+ port: port !== undefined ? +port : undefined,
233
+ properties,
234
+ };
235
+ }
236
+ export function requiredTargetAndQuantityFromOptions(options) {
237
+ if (options.target === undefined) {
238
+ throw new Error('No target provided. Use --target');
239
+ }
240
+ if (options.quantity === undefined) {
241
+ throw new Error('No quantity provided. Use --quantity');
242
+ }
243
+ return {
244
+ target: options.target,
245
+ ioQuantity: new IOToken(+options.quantity),
246
+ };
247
+ }
248
+ export function redelegateParamsFromOptions(options) {
249
+ const { target, ioQuantity } = requiredTargetAndQuantityFromOptions(options);
250
+ const source = options.source;
251
+ if (source === undefined) {
252
+ throw new Error('No source provided. Use --source');
253
+ }
254
+ return {
255
+ target,
256
+ source,
257
+ vaultId: options.vaultId,
258
+ stakeQty: ioQuantity.toMIO(),
259
+ };
260
+ }
261
+ export function recordTypeFromOptions(options) {
262
+ options.type ??= 'lease';
263
+ if (options.type !== 'lease' && options.type !== 'permabuy') {
264
+ throw new Error(`Invalid type. Valid types are: lease, permabuy`);
265
+ }
266
+ return options.type;
267
+ }
268
+ export function requiredMIOFromOptions(options, key) {
269
+ if (options[key] === undefined) {
270
+ throw new Error(`No ${key} provided. Use --${key} denominated in IO`);
271
+ }
272
+ return new IOToken(+options[key]).toMIO();
273
+ }
274
+ export async function assertEnoughBalance(io, address, ioQuantity) {
275
+ const balance = await io.getBalance({ address });
276
+ if (balance < ioQuantity.toMIO().valueOf()) {
277
+ throw new Error(`Insufficient IO balance for action. Balance available: ${new mIOToken(balance).toIO()} IO`);
278
+ }
279
+ }
280
+ export async function confirmationPrompt(message) {
281
+ const { confirm } = await prompts({
282
+ type: 'confirm',
283
+ name: 'confirm',
284
+ message,
285
+ });
286
+ return confirm;
287
+ }
288
+ export async function assertConfirmationPrompt(message, options) {
289
+ if (options.skipConfirmation) {
290
+ return true;
291
+ }
292
+ return confirmationPrompt(message);
293
+ }
294
+ export function requiredProcessIdFromOptions(o) {
295
+ if (o.processId === undefined) {
296
+ throw new Error('--process-id is required');
297
+ }
298
+ return o.processId;
299
+ }
300
+ function ANTProcessFromOptions(options) {
301
+ return new AOProcess({
302
+ processId: requiredProcessIdFromOptions(options),
303
+ ao: connect({
304
+ CU_URL: options.cuUrl,
305
+ }),
306
+ });
307
+ }
308
+ export function readANTFromOptions(options) {
309
+ return ANT.init({
310
+ process: ANTProcessFromOptions(options),
311
+ });
312
+ }
313
+ export function writeANTFromOptions(options, signer) {
314
+ signer ??= requiredContractSignerFromOptions(options).signer;
315
+ return ANT.init({
316
+ process: ANTProcessFromOptions(options),
317
+ signer,
318
+ });
319
+ }
320
+ export function requiredStringFromOptions(options, key) {
321
+ const value = options[key];
322
+ if (value === undefined) {
323
+ throw new Error(`--${key} is required`);
324
+ }
325
+ return value;
326
+ }
327
+ export function requiredStringArrayFromOptions(options, key) {
328
+ const value = options[key];
329
+ if (value === undefined) {
330
+ throw new Error(`--${key} is required`);
331
+ }
332
+ if (!Array.isArray(value)) {
333
+ throw new Error(`--${key} must be an array`);
334
+ }
335
+ return value;
336
+ }
337
+ export function positiveIntegerFromOptions(options, key) {
338
+ const value = options[key];
339
+ if (value === undefined) {
340
+ return undefined;
341
+ }
342
+ const numberValue = +value;
343
+ if (isNaN(numberValue) || numberValue <= 0) {
344
+ throw new Error(`Invalid ${key}: ${value}, must be a positive number`);
345
+ }
346
+ return numberValue;
347
+ }
348
+ export function requiredPositiveIntegerFromOptions(options, key) {
349
+ const value = positiveIntegerFromOptions(options, key);
350
+ if (value === undefined) {
351
+ throw new Error(`--${key} is required`);
352
+ }
353
+ return value;
354
+ }
355
+ export function getANTStateFromOptions(options) {
356
+ return initANTStateForAddress({
357
+ owner: requiredAddressFromOptions(options),
358
+ targetId: options.target,
359
+ controllers: options.controllers,
360
+ description: options.description,
361
+ ticker: options.ticker,
362
+ name: options.name,
363
+ keywords: options.keywords,
364
+ ttlSeconds: options.ttlSeconds !== undefined ? +options.ttlSeconds : 0,
365
+ });
366
+ }