@twin.org/nft-cli 0.0.1-next.8 → 0.0.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.
@@ -2,15 +2,29 @@ import path from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { CLIParam, CLIDisplay, CLIOptions, CLIUtils, CLIBase } from '@twin.org/cli-core';
4
4
  import { buildCommandMnemonic, buildCommandAddress } from '@twin.org/crypto-cli';
5
- import { buildCommandFaucet } from '@twin.org/wallet-cli';
6
- import { I18n, Converter, StringHelper, Is } from '@twin.org/core';
5
+ import { setupWalletConnector, buildCommandFaucet } from '@twin.org/wallet-cli';
6
+ import { I18n, Is, Converter, StringHelper } from '@twin.org/core';
7
7
  import { IotaNftConnector, IotaNftUtils } from '@twin.org/nft-connector-iota';
8
8
  import { VaultConnectorFactory } from '@twin.org/vault-models';
9
- import { Command } from 'commander';
9
+ import { WalletConnectorFactory } from '@twin.org/wallet-models';
10
+ import { Command, Option } from 'commander';
10
11
  import { MemoryEntityStorageConnector } from '@twin.org/entity-storage-connector-memory';
11
12
  import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
12
13
  import { initSchema, EntityStorageVaultConnector } from '@twin.org/vault-connector-entity-storage';
13
14
 
15
+ // Copyright 2024 IOTA Stiftung.
16
+ // SPDX-License-Identifier: Apache-2.0.
17
+ /**
18
+ * The NFT connector types.
19
+ */
20
+ // eslint-disable-next-line @typescript-eslint/naming-convention
21
+ const NftConnectorTypes = {
22
+ /**
23
+ * IOTA.
24
+ */
25
+ Iota: "iota"
26
+ };
27
+
14
28
  // Copyright 2024 IOTA Stiftung.
15
29
  // SPDX-License-Identifier: Apache-2.0.
16
30
  /**
@@ -27,6 +41,29 @@ function setupVault() {
27
41
  const vaultConnector = new EntityStorageVaultConnector();
28
42
  VaultConnectorFactory.register("vault", () => vaultConnector);
29
43
  }
44
+ /**
45
+ * Setup the NFT connector for use in the CLI commands.
46
+ * @param options The options for the NFT connector.
47
+ * @param options.nodeEndpoint The node endpoint.
48
+ * @param options.network The network.
49
+ * @param options.vaultSeedId The vault seed ID.
50
+ * @param options.walletAddressIndex The wallet address index.
51
+ * @param connector The connector to use.
52
+ * @returns The NFT connector.
53
+ */
54
+ function setupNftConnector(options, connector) {
55
+ connector ??= NftConnectorTypes.Iota;
56
+ return new IotaNftConnector({
57
+ config: {
58
+ clientOptions: {
59
+ url: options.nodeEndpoint
60
+ },
61
+ network: options.network ?? "",
62
+ vaultSeedId: options.vaultSeedId,
63
+ walletAddressIndex: options.walletAddressIndex ?? 0
64
+ }
65
+ });
66
+ }
30
67
 
31
68
  // Copyright 2024 IOTA Stiftung.
32
69
  // SPDX-License-Identifier: Apache-2.0.
@@ -41,10 +78,13 @@ function buildCommandNftBurn() {
41
78
  .summary(I18n.formatMessage("commands.nft-burn.summary"))
42
79
  .description(I18n.formatMessage("commands.nft-burn.description"))
43
80
  .requiredOption(I18n.formatMessage("commands.nft-burn.options.seed.param"), I18n.formatMessage("commands.nft-burn.options.seed.description"))
44
- .requiredOption(I18n.formatMessage("commands.nft-burn.options.issuer.param"), I18n.formatMessage("commands.nft-burn.options.issuer.description"))
45
81
  .requiredOption(I18n.formatMessage("commands.nft-burn.options.id.param"), I18n.formatMessage("commands.nft-burn.options.id.description"));
46
82
  command
83
+ .addOption(new Option(I18n.formatMessage("commands.common.options.connector.param"), I18n.formatMessage("commands.common.options.connector.description"))
84
+ .choices(Object.values(NftConnectorTypes))
85
+ .default(NftConnectorTypes.Iota))
47
86
  .option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
87
+ .option(I18n.formatMessage("commands.common.options.network.param"), I18n.formatMessage("commands.common.options.network.description"), "!NETWORK")
48
88
  .option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
49
89
  .action(actionCommandNftBurn);
50
90
  return command;
@@ -53,41 +93,43 @@ function buildCommandNftBurn() {
53
93
  * Action the nft burn command.
54
94
  * @param opts The options for the command.
55
95
  * @param opts.seed The seed required for signing by the issuer.
56
- * @param opts.issuer The issuer address of the NFT.
57
96
  * @param opts.id The id of the NFT to burn in urn format.
97
+ * @param opts.connector The connector to perform the operations with.
58
98
  * @param opts.node The node URL.
99
+ * @param opts.network The network to use for connector.
59
100
  * @param opts.explorer The explorer URL.
60
101
  */
61
102
  async function actionCommandNftBurn(opts) {
62
103
  const seed = CLIParam.hexBase64("seed", opts.seed);
63
- const issuer = CLIParam.bech32("issuer", opts.issuer);
64
104
  const id = CLIParam.stringValue("id", opts.id);
65
105
  const nodeEndpoint = CLIParam.url("node", opts.node);
106
+ const network = opts.connector === NftConnectorTypes.Iota
107
+ ? CLIParam.stringValue("network", opts.network)
108
+ : undefined;
66
109
  const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
67
- CLIDisplay.value(I18n.formatMessage("commands.nft-burn.labels.issuer"), issuer);
68
110
  CLIDisplay.value(I18n.formatMessage("commands.nft-burn.labels.nftId"), id);
69
111
  CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
112
+ if (Is.stringValue(network)) {
113
+ CLIDisplay.value(I18n.formatMessage("commands.common.labels.network"), network);
114
+ }
70
115
  CLIDisplay.break();
71
116
  setupVault();
72
117
  const localIdentity = "local";
73
118
  const vaultSeedId = "local-seed";
74
119
  const vaultConnector = VaultConnectorFactory.get("vault");
75
120
  await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
76
- const iotaNftConnector = new IotaNftConnector({
77
- config: {
78
- clientOptions: {
79
- nodes: [nodeEndpoint],
80
- localPow: true
81
- },
82
- vaultSeedId
83
- }
84
- });
121
+ const walletConnector = setupWalletConnector({ nodeEndpoint, network, vaultSeedId }, opts.connector);
122
+ WalletConnectorFactory.register("wallet", () => walletConnector);
123
+ const nftConnector = setupNftConnector({ nodeEndpoint, network, vaultSeedId }, opts.connector);
124
+ if (Is.function(nftConnector.start)) {
125
+ await nftConnector.start(localIdentity);
126
+ }
85
127
  CLIDisplay.task(I18n.formatMessage("commands.nft-burn.progress.burningNft"));
86
128
  CLIDisplay.break();
87
129
  CLIDisplay.spinnerStart();
88
- await iotaNftConnector.burn(localIdentity, id);
130
+ await nftConnector.burn(localIdentity, id);
89
131
  CLIDisplay.spinnerStop();
90
- CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaNftUtils.nftIdToAddress(id)}`);
132
+ CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/object/${IotaNftUtils.nftIdToObjectId(id)}?network=${network}`);
91
133
  CLIDisplay.break();
92
134
  CLIDisplay.done();
93
135
  }
@@ -106,6 +148,7 @@ function buildCommandNftMint() {
106
148
  .description(I18n.formatMessage("commands.nft-mint.description"))
107
149
  .requiredOption(I18n.formatMessage("commands.nft-mint.options.seed.param"), I18n.formatMessage("commands.nft-mint.options.seed.description"))
108
150
  .requiredOption(I18n.formatMessage("commands.nft-mint.options.issuer.param"), I18n.formatMessage("commands.nft-mint.options.issuer.description"))
151
+ .option(I18n.formatMessage("commands.nft-mint.options.wallet-address-index.param"), I18n.formatMessage("commands.nft-mint.options.wallet-address-index.description"), "0")
109
152
  .requiredOption(I18n.formatMessage("commands.nft-mint.options.tag.param"), I18n.formatMessage("commands.nft-mint.options.tag.description"))
110
153
  .option(I18n.formatMessage("commands.nft-mint.options.immutable-json.param"), I18n.formatMessage("commands.nft-mint.options.immutable-json.description"))
111
154
  .option(I18n.formatMessage("commands.nft-mint.options.mutable-json.param"), I18n.formatMessage("commands.nft-mint.options.mutable-json.description"));
@@ -117,8 +160,12 @@ function buildCommandNftMint() {
117
160
  mergeEnv: true
118
161
  });
119
162
  command
120
- .option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
163
+ .addOption(new Option(I18n.formatMessage("commands.common.options.connector.param"), I18n.formatMessage("commands.common.options.connector.description"))
164
+ .choices(Object.values(NftConnectorTypes))
165
+ .default(NftConnectorTypes.Iota))
166
+ .option(I18n.formatMessage("commands.common.options.network.param"), I18n.formatMessage("commands.common.options.network.description"), "!NETWORK")
121
167
  .option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
168
+ .option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
122
169
  .action(actionCommandNftMint);
123
170
  return command;
124
171
  }
@@ -126,16 +173,22 @@ function buildCommandNftMint() {
126
173
  * Action the nft mint command.
127
174
  * @param opts The options for the command.
128
175
  * @param opts.seed The seed required for signing by the issuer.
129
- * @param opts.issuer The issuer address of the NFT.
176
+ * @param opts.issuer The identity of the issuer.
177
+ * @param opts.walletAddressIndex The wallet address index.
130
178
  * @param opts.tag The tag for the NFT.
131
179
  * @param opts.immutableJson Filename of the immutable JSON data.
132
180
  * @param opts.mutableJson Filename of the mutable JSON data.
181
+ * @param opts.connector The connector to perform the operations with.
133
182
  * @param opts.node The node URL.
183
+ * @param opts.network The network to use for connector.
134
184
  * @param opts.explorer The explorer URL.
135
185
  */
136
186
  async function actionCommandNftMint(opts) {
137
187
  const seed = CLIParam.hexBase64("seed", opts.seed);
138
- const issuer = CLIParam.bech32("issuer", opts.issuer);
188
+ const issuer = CLIParam.stringValue("issuer", opts.issuer);
189
+ const walletAddressIndex = Is.empty(opts.walletAddressIndex)
190
+ ? undefined
191
+ : CLIParam.integer("wallet-address-index", opts.walletAddressIndex);
139
192
  const tag = CLIParam.stringValue("tag", opts.tag);
140
193
  const immutableJson = opts.immutableJson
141
194
  ? path.resolve(opts.immutableJson)
@@ -144,8 +197,14 @@ async function actionCommandNftMint(opts) {
144
197
  ? path.resolve(opts.mutableJson)
145
198
  : undefined;
146
199
  const nodeEndpoint = CLIParam.url("node", opts.node);
200
+ const network = opts.connector === NftConnectorTypes.Iota
201
+ ? CLIParam.stringValue("network", opts.network)
202
+ : undefined;
147
203
  const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
148
204
  CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.issuer"), issuer);
205
+ if (Is.integer(walletAddressIndex)) {
206
+ CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.walletAddressIndex"), walletAddressIndex);
207
+ }
149
208
  CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.tag"), tag);
150
209
  if (Is.stringValue(immutableJson)) {
151
210
  CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.immutableJsonFilename"), immutableJson);
@@ -154,21 +213,21 @@ async function actionCommandNftMint(opts) {
154
213
  CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.mutableJsonFilename"), mutableJson);
155
214
  }
156
215
  CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
216
+ if (Is.stringValue(network)) {
217
+ CLIDisplay.value(I18n.formatMessage("commands.common.labels.network"), network);
218
+ }
157
219
  CLIDisplay.break();
158
220
  setupVault();
159
- const localIdentity = "local";
221
+ const localIdentity = issuer;
160
222
  const vaultSeedId = "local-seed";
161
223
  const vaultConnector = VaultConnectorFactory.get("vault");
162
224
  await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
163
- const iotaNftConnector = new IotaNftConnector({
164
- config: {
165
- clientOptions: {
166
- nodes: [nodeEndpoint],
167
- localPow: true
168
- },
169
- vaultSeedId
170
- }
171
- });
225
+ const walletConnector = setupWalletConnector({ nodeEndpoint, network, vaultSeedId }, opts.connector);
226
+ WalletConnectorFactory.register("wallet", () => walletConnector);
227
+ const nftConnector = setupNftConnector({ nodeEndpoint, network, vaultSeedId, walletAddressIndex }, opts.connector);
228
+ if (Is.function(nftConnector.start)) {
229
+ await nftConnector.start(localIdentity);
230
+ }
172
231
  const immutableJsonData = Is.stringValue(immutableJson)
173
232
  ? await CLIUtils.readJsonFile(immutableJson)
174
233
  : undefined;
@@ -188,7 +247,7 @@ async function actionCommandNftMint(opts) {
188
247
  CLIDisplay.task(I18n.formatMessage("commands.nft-mint.progress.mintingNft"));
189
248
  CLIDisplay.break();
190
249
  CLIDisplay.spinnerStart();
191
- const nftId = await iotaNftConnector.mint(localIdentity, issuer, tag, immutableJsonData, mutableJsonData);
250
+ const nftId = await nftConnector.mint(localIdentity, tag, immutableJsonData, mutableJsonData);
192
251
  CLIDisplay.spinnerStop();
193
252
  if (opts.console) {
194
253
  CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.nftId"), nftId);
@@ -200,7 +259,7 @@ async function actionCommandNftMint(opts) {
200
259
  if (Is.stringValue(opts?.env)) {
201
260
  await CLIUtils.writeEnvFile(opts.env, [`NFT_ID="${nftId}"`], opts.mergeEnv);
202
261
  }
203
- CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaNftUtils.nftIdToAddress(nftId)}`);
262
+ CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/object/${IotaNftUtils.nftIdToObjectId(nftId)}?network=${network}`);
204
263
  CLIDisplay.break();
205
264
  CLIDisplay.done();
206
265
  }
@@ -226,7 +285,11 @@ function buildCommandNftResolve() {
226
285
  mergeEnv: false
227
286
  });
228
287
  command
288
+ .addOption(new Option(I18n.formatMessage("commands.common.options.connector.param"), I18n.formatMessage("commands.common.options.connector.description"))
289
+ .choices(Object.values(NftConnectorTypes))
290
+ .default(NftConnectorTypes.Iota))
229
291
  .option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
292
+ .option(I18n.formatMessage("commands.common.options.network.param"), I18n.formatMessage("commands.common.options.network.description"), "!NETWORK")
230
293
  .option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
231
294
  .action(actionCommandNftResolve);
232
295
  return command;
@@ -235,29 +298,32 @@ function buildCommandNftResolve() {
235
298
  * Action the nft resolve command.
236
299
  * @param opts The options for the command.
237
300
  * @param opts.id The id of the NFT to resolve in urn format.
301
+ * @param opts.connector The connector to perform the operations with.
238
302
  * @param opts.node The node URL.
303
+ * @param opts.network The network to use for connector.
239
304
  * @param opts.explorer The explorer URL.
240
305
  */
241
306
  async function actionCommandNftResolve(opts) {
242
307
  const id = CLIParam.stringValue("id", opts.id);
243
308
  const nodeEndpoint = CLIParam.url("node", opts.node);
309
+ const network = opts.connector === NftConnectorTypes.Iota
310
+ ? CLIParam.stringValue("network", opts.network)
311
+ : undefined;
244
312
  const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
245
313
  CLIDisplay.value(I18n.formatMessage("commands.nft-resolve.labels.nftId"), id);
246
314
  CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
315
+ if (Is.stringValue(network)) {
316
+ CLIDisplay.value(I18n.formatMessage("commands.common.labels.network"), network);
317
+ }
247
318
  CLIDisplay.break();
248
319
  setupVault();
249
- const iotaNftConnector = new IotaNftConnector({
250
- config: {
251
- clientOptions: {
252
- nodes: [nodeEndpoint],
253
- localPow: true
254
- }
255
- }
256
- });
320
+ const walletConnector = setupWalletConnector({ nodeEndpoint, network }, opts.connector);
321
+ WalletConnectorFactory.register("wallet", () => walletConnector);
322
+ const nftConnector = setupNftConnector({ nodeEndpoint, network }, opts.connector);
257
323
  CLIDisplay.task(I18n.formatMessage("commands.nft-resolve.progress.resolvingNft"));
258
324
  CLIDisplay.break();
259
325
  CLIDisplay.spinnerStart();
260
- const nft = await iotaNftConnector.resolve(id);
326
+ const nft = await nftConnector.resolve(id);
261
327
  CLIDisplay.spinnerStop();
262
328
  if (opts.console) {
263
329
  CLIDisplay.section(I18n.formatMessage("commands.nft-resolve.labels.nft"));
@@ -267,7 +333,7 @@ async function actionCommandNftResolve(opts) {
267
333
  if (Is.stringValue(opts?.json)) {
268
334
  await CLIUtils.writeJsonFile(opts.json, nft, opts.mergeJson);
269
335
  }
270
- CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaNftUtils.nftIdToAddress(id)}`);
336
+ CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/object/${IotaNftUtils.nftIdToObjectId(id)}?network=${network}`);
271
337
  CLIDisplay.break();
272
338
  CLIDisplay.done();
273
339
  }
@@ -286,9 +352,14 @@ function buildCommandNftTransfer() {
286
352
  .description(I18n.formatMessage("commands.nft-transfer.description"))
287
353
  .requiredOption(I18n.formatMessage("commands.nft-transfer.options.seed.param"), I18n.formatMessage("commands.nft-transfer.options.seed.description"))
288
354
  .requiredOption(I18n.formatMessage("commands.nft-transfer.options.id.param"), I18n.formatMessage("commands.nft-transfer.options.id.description"))
289
- .requiredOption(I18n.formatMessage("commands.nft-transfer.options.recipient.param"), I18n.formatMessage("commands.nft-transfer.options.recipient.description"));
355
+ .requiredOption(I18n.formatMessage("commands.nft-transfer.options.recipient-identity.param"), I18n.formatMessage("commands.nft-transfer.options.recipient-identity.description"))
356
+ .requiredOption(I18n.formatMessage("commands.nft-transfer.options.recipient-address.param"), I18n.formatMessage("commands.nft-transfer.options.recipient-address.description"));
290
357
  command
358
+ .addOption(new Option(I18n.formatMessage("commands.common.options.connector.param"), I18n.formatMessage("commands.common.options.connector.description"))
359
+ .choices(Object.values(NftConnectorTypes))
360
+ .default(NftConnectorTypes.Iota))
291
361
  .option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
362
+ .option(I18n.formatMessage("commands.common.options.network.param"), I18n.formatMessage("commands.common.options.network.description"), "!NETWORK")
292
363
  .option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
293
364
  .action(actionCommandNftTransfer);
294
365
  return command;
@@ -298,40 +369,50 @@ function buildCommandNftTransfer() {
298
369
  * @param opts The options for the command.
299
370
  * @param opts.seed The seed required for signing by the issuer.
300
371
  * @param opts.id The id of the NFT to transfer in urn format.
301
- * @param opts.recipient The recipient address of the NFT.
372
+ * @param opts.recipientIdentity The recipient address of the NFT.
373
+ * @param opts.recipientAddress The recipient address of the NFT.
374
+ * @param opts.connector The connector to perform the operations with.
302
375
  * @param opts.node The node URL.
376
+ * @param opts.network The network to use for connector.
303
377
  * @param opts.explorer The explorer URL.
304
378
  */
305
379
  async function actionCommandNftTransfer(opts) {
306
380
  const seed = CLIParam.hexBase64("seed", opts.seed);
307
381
  const id = CLIParam.stringValue("id", opts.id);
308
- const recipient = CLIParam.bech32("recipient", opts.recipient);
382
+ const recipientIdentity = CLIParam.stringValue("recipientIdentity", opts.recipientIdentity);
383
+ const recipientAddress = opts.connector === NftConnectorTypes.Iota
384
+ ? Converter.bytesToHex(CLIParam.hex("recipientAddress", opts.recipientAddress), true)
385
+ : CLIParam.bech32("recipientAddress", opts.recipientAddress);
309
386
  const nodeEndpoint = CLIParam.url("node", opts.node);
387
+ const network = opts.connector === NftConnectorTypes.Iota
388
+ ? CLIParam.stringValue("network", opts.network)
389
+ : undefined;
310
390
  const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
311
391
  CLIDisplay.value(I18n.formatMessage("commands.nft-transfer.labels.nftId"), id);
312
- CLIDisplay.value(I18n.formatMessage("commands.nft-transfer.labels.recipient"), recipient);
392
+ CLIDisplay.value(I18n.formatMessage("commands.nft-transfer.labels.recipientIdentity"), recipientIdentity);
393
+ CLIDisplay.value(I18n.formatMessage("commands.nft-transfer.labels.recipientAddress"), recipientAddress);
313
394
  CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
395
+ if (Is.stringValue(network)) {
396
+ CLIDisplay.value(I18n.formatMessage("commands.common.labels.network"), network);
397
+ }
314
398
  CLIDisplay.break();
315
399
  setupVault();
400
+ const walletConnector = setupWalletConnector({ nodeEndpoint, network }, opts.connector);
401
+ WalletConnectorFactory.register("wallet", () => walletConnector);
316
402
  const localIdentity = "local";
317
403
  const vaultSeedId = "local-seed";
318
404
  const vaultConnector = VaultConnectorFactory.get("vault");
319
405
  await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
320
- const iotaNftConnector = new IotaNftConnector({
321
- config: {
322
- clientOptions: {
323
- nodes: [nodeEndpoint],
324
- localPow: true
325
- },
326
- vaultSeedId
327
- }
328
- });
406
+ const nftConnector = setupNftConnector({ nodeEndpoint, network, vaultSeedId }, opts.connector);
407
+ if (Is.function(nftConnector.start)) {
408
+ await nftConnector.start(localIdentity);
409
+ }
329
410
  CLIDisplay.task(I18n.formatMessage("commands.nft-transfer.progress.transferringNft"));
330
411
  CLIDisplay.break();
331
412
  CLIDisplay.spinnerStart();
332
- await iotaNftConnector.transfer(localIdentity, id, recipient);
413
+ await nftConnector.transfer(localIdentity, id, recipientIdentity, recipientAddress);
333
414
  CLIDisplay.spinnerStop();
334
- CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaNftUtils.nftIdToAddress(id)}`);
415
+ CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/object/${IotaNftUtils.nftIdToObjectId(id)}?network=${network}`);
335
416
  CLIDisplay.break();
336
417
  CLIDisplay.done();
337
418
  }
@@ -354,7 +435,7 @@ class CLI extends CLIBase {
354
435
  return this.execute({
355
436
  title: "TWIN NFT",
356
437
  appName: "twin-nft",
357
- version: "0.0.1-next.8",
438
+ version: "0.0.1", // x-release-please-version
358
439
  icon: "🌍",
359
440
  supportsEnvFiles: true,
360
441
  overrideOutputWidth: options?.overrideOutputWidth
@@ -378,4 +459,4 @@ class CLI extends CLIBase {
378
459
  }
379
460
  }
380
461
 
381
- export { CLI, actionCommandNftBurn, actionCommandNftMint, actionCommandNftResolve, actionCommandNftTransfer, buildCommandNftBurn, buildCommandNftMint, buildCommandNftResolve, buildCommandNftTransfer };
462
+ export { CLI, NftConnectorTypes, actionCommandNftBurn, actionCommandNftMint, actionCommandNftResolve, actionCommandNftTransfer, buildCommandNftBurn, buildCommandNftMint, buildCommandNftResolve, buildCommandNftTransfer, setupNftConnector, setupVault };