@twin.org/nft-cli 0.0.1-next.14 → 0.0.1-next.15
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.
- package/dist/cjs/index.cjs +145 -48
- package/dist/esm/index.mjs +145 -51
- package/dist/locales/en.json +57 -10
- package/dist/types/commands/nftBurn.d.ts +5 -0
- package/dist/types/commands/nftMint.d.ts +5 -0
- package/dist/types/commands/nftResolve.d.ts +5 -0
- package/dist/types/commands/nftTransfer.d.ts +5 -0
- package/dist/types/commands/setupCommands.d.ts +16 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/models/nftConnectorTypes.d.ts +17 -0
- package/docs/changelog.md +1 -1
- package/docs/examples.md +6 -6
- package/docs/reference/functions/actionCommandNftBurn.md +12 -0
- package/docs/reference/functions/actionCommandNftTransfer.md +12 -0
- package/docs/reference/functions/setupNftConnector.md +41 -0
- package/docs/reference/functions/setupVault.md +9 -0
- package/docs/reference/index.md +10 -0
- package/docs/reference/type-aliases/NftConnectorTypes.md +5 -0
- package/docs/reference/variables/NftConnectorTypes.md +19 -0
- package/locales/en.json +14 -4
- package/package.json +6 -5
package/dist/esm/index.mjs
CHANGED
|
@@ -3,14 +3,32 @@ 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
5
|
import { buildCommandFaucet } from '@twin.org/wallet-cli';
|
|
6
|
-
import { I18n, Converter,
|
|
6
|
+
import { I18n, Converter, Is, StringHelper } from '@twin.org/core';
|
|
7
7
|
import { IotaNftConnector, IotaNftUtils } from '@twin.org/nft-connector-iota';
|
|
8
|
+
import { IotaRebasedNftConnector, IotaRebasedNftUtils } from '@twin.org/nft-connector-iota-rebased';
|
|
8
9
|
import { VaultConnectorFactory } from '@twin.org/vault-models';
|
|
9
|
-
import { Command } from 'commander';
|
|
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
|
+
* IOTA Rebased.
|
|
28
|
+
*/
|
|
29
|
+
IotaRebased: "iota-rebased"
|
|
30
|
+
};
|
|
31
|
+
|
|
14
32
|
// Copyright 2024 IOTA Stiftung.
|
|
15
33
|
// SPDX-License-Identifier: Apache-2.0.
|
|
16
34
|
/**
|
|
@@ -27,6 +45,42 @@ function setupVault() {
|
|
|
27
45
|
const vaultConnector = new EntityStorageVaultConnector();
|
|
28
46
|
VaultConnectorFactory.register("vault", () => vaultConnector);
|
|
29
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Setup the NFT connector for use in the CLI commands.
|
|
50
|
+
* @param options The options for the NFT connector.
|
|
51
|
+
* @param options.nodeEndpoint The node endpoint.
|
|
52
|
+
* @param options.network The network.
|
|
53
|
+
* @param options.vaultSeedId The vault seed ID.
|
|
54
|
+
* @param connector The connector to use.
|
|
55
|
+
* @returns The NFT connector.
|
|
56
|
+
*/
|
|
57
|
+
function setupNftConnector(options, connector) {
|
|
58
|
+
connector ??= NftConnectorTypes.Iota;
|
|
59
|
+
let instance;
|
|
60
|
+
if (connector === NftConnectorTypes.IotaRebased) {
|
|
61
|
+
instance = new IotaRebasedNftConnector({
|
|
62
|
+
config: {
|
|
63
|
+
clientOptions: {
|
|
64
|
+
url: options.nodeEndpoint
|
|
65
|
+
},
|
|
66
|
+
network: options.network ?? "",
|
|
67
|
+
vaultSeedId: options.vaultSeedId
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
instance = new IotaNftConnector({
|
|
73
|
+
config: {
|
|
74
|
+
clientOptions: {
|
|
75
|
+
nodes: [options.nodeEndpoint],
|
|
76
|
+
localPow: true
|
|
77
|
+
},
|
|
78
|
+
vaultSeedId: options.vaultSeedId
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return instance;
|
|
83
|
+
}
|
|
30
84
|
|
|
31
85
|
// Copyright 2024 IOTA Stiftung.
|
|
32
86
|
// SPDX-License-Identifier: Apache-2.0.
|
|
@@ -44,7 +98,11 @@ function buildCommandNftBurn() {
|
|
|
44
98
|
.requiredOption(I18n.formatMessage("commands.nft-burn.options.issuer.param"), I18n.formatMessage("commands.nft-burn.options.issuer.description"))
|
|
45
99
|
.requiredOption(I18n.formatMessage("commands.nft-burn.options.id.param"), I18n.formatMessage("commands.nft-burn.options.id.description"));
|
|
46
100
|
command
|
|
101
|
+
.addOption(new Option(I18n.formatMessage("commands.common.options.connector.param"), I18n.formatMessage("commands.common.options.connector.description"))
|
|
102
|
+
.choices(Object.values(NftConnectorTypes))
|
|
103
|
+
.default(NftConnectorTypes.Iota))
|
|
47
104
|
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
105
|
+
.option(I18n.formatMessage("commands.common.options.network.param"), I18n.formatMessage("commands.common.options.network.description"), "!NETWORK")
|
|
48
106
|
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
49
107
|
.action(actionCommandNftBurn);
|
|
50
108
|
return command;
|
|
@@ -55,39 +113,46 @@ function buildCommandNftBurn() {
|
|
|
55
113
|
* @param opts.seed The seed required for signing by the issuer.
|
|
56
114
|
* @param opts.issuer The issuer address of the NFT.
|
|
57
115
|
* @param opts.id The id of the NFT to burn in urn format.
|
|
116
|
+
* @param opts.connector The connector to perform the operations with.
|
|
58
117
|
* @param opts.node The node URL.
|
|
118
|
+
* @param opts.network The network to use for rebased connector.
|
|
59
119
|
* @param opts.explorer The explorer URL.
|
|
60
120
|
*/
|
|
61
121
|
async function actionCommandNftBurn(opts) {
|
|
62
122
|
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
63
|
-
const issuer =
|
|
123
|
+
const issuer = opts.connector === NftConnectorTypes.IotaRebased
|
|
124
|
+
? Converter.bytesToHex(CLIParam.hex("issuer", opts.issuer), true)
|
|
125
|
+
: CLIParam.bech32("issuer", opts.issuer);
|
|
64
126
|
const id = CLIParam.stringValue("id", opts.id);
|
|
65
127
|
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
128
|
+
const network = opts.connector === NftConnectorTypes.IotaRebased
|
|
129
|
+
? CLIParam.stringValue("network", opts.network)
|
|
130
|
+
: undefined;
|
|
66
131
|
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
67
132
|
CLIDisplay.value(I18n.formatMessage("commands.nft-burn.labels.issuer"), issuer);
|
|
68
133
|
CLIDisplay.value(I18n.formatMessage("commands.nft-burn.labels.nftId"), id);
|
|
69
134
|
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
135
|
+
if (Is.stringValue(network)) {
|
|
136
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.network"), network);
|
|
137
|
+
}
|
|
70
138
|
CLIDisplay.break();
|
|
71
139
|
setupVault();
|
|
72
140
|
const localIdentity = "local";
|
|
73
141
|
const vaultSeedId = "local-seed";
|
|
74
142
|
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
75
143
|
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
localPow: true
|
|
81
|
-
},
|
|
82
|
-
vaultSeedId
|
|
83
|
-
}
|
|
84
|
-
});
|
|
144
|
+
const nftConnector = setupNftConnector({ nodeEndpoint, network, vaultSeedId }, opts.connector);
|
|
145
|
+
if (Is.function(nftConnector.start)) {
|
|
146
|
+
await nftConnector.start(localIdentity);
|
|
147
|
+
}
|
|
85
148
|
CLIDisplay.task(I18n.formatMessage("commands.nft-burn.progress.burningNft"));
|
|
86
149
|
CLIDisplay.break();
|
|
87
150
|
CLIDisplay.spinnerStart();
|
|
88
|
-
await
|
|
151
|
+
await nftConnector.burn(localIdentity, id);
|
|
89
152
|
CLIDisplay.spinnerStop();
|
|
90
|
-
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"),
|
|
153
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), opts.connector === NftConnectorTypes.IotaRebased
|
|
154
|
+
? `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/object/${IotaRebasedNftUtils.nftIdToObjectId(id)}?network=${network}`
|
|
155
|
+
: `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaNftUtils.nftIdToAddress(id)}`);
|
|
91
156
|
CLIDisplay.break();
|
|
92
157
|
CLIDisplay.done();
|
|
93
158
|
}
|
|
@@ -117,8 +182,12 @@ function buildCommandNftMint() {
|
|
|
117
182
|
mergeEnv: true
|
|
118
183
|
});
|
|
119
184
|
command
|
|
120
|
-
.
|
|
185
|
+
.addOption(new Option(I18n.formatMessage("commands.common.options.connector.param"), I18n.formatMessage("commands.common.options.connector.description"))
|
|
186
|
+
.choices(Object.values(NftConnectorTypes))
|
|
187
|
+
.default(NftConnectorTypes.Iota))
|
|
188
|
+
.option(I18n.formatMessage("commands.common.options.network.param"), I18n.formatMessage("commands.common.options.network.description"), "!NETWORK")
|
|
121
189
|
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
190
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
122
191
|
.action(actionCommandNftMint);
|
|
123
192
|
return command;
|
|
124
193
|
}
|
|
@@ -130,12 +199,16 @@ function buildCommandNftMint() {
|
|
|
130
199
|
* @param opts.tag The tag for the NFT.
|
|
131
200
|
* @param opts.immutableJson Filename of the immutable JSON data.
|
|
132
201
|
* @param opts.mutableJson Filename of the mutable JSON data.
|
|
202
|
+
* @param opts.connector The connector to perform the operations with.
|
|
133
203
|
* @param opts.node The node URL.
|
|
204
|
+
* @param opts.network The network to use for rebased connector.
|
|
134
205
|
* @param opts.explorer The explorer URL.
|
|
135
206
|
*/
|
|
136
207
|
async function actionCommandNftMint(opts) {
|
|
137
208
|
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
138
|
-
const issuer =
|
|
209
|
+
const issuer = opts.connector === NftConnectorTypes.IotaRebased
|
|
210
|
+
? Converter.bytesToHex(CLIParam.hex("issuer", opts.issuer), true)
|
|
211
|
+
: CLIParam.bech32("issuer", opts.issuer);
|
|
139
212
|
const tag = CLIParam.stringValue("tag", opts.tag);
|
|
140
213
|
const immutableJson = opts.immutableJson
|
|
141
214
|
? path.resolve(opts.immutableJson)
|
|
@@ -144,6 +217,9 @@ async function actionCommandNftMint(opts) {
|
|
|
144
217
|
? path.resolve(opts.mutableJson)
|
|
145
218
|
: undefined;
|
|
146
219
|
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
220
|
+
const network = opts.connector === NftConnectorTypes.IotaRebased
|
|
221
|
+
? CLIParam.stringValue("network", opts.network)
|
|
222
|
+
: undefined;
|
|
147
223
|
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
148
224
|
CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.issuer"), issuer);
|
|
149
225
|
CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.tag"), tag);
|
|
@@ -154,21 +230,19 @@ async function actionCommandNftMint(opts) {
|
|
|
154
230
|
CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.mutableJsonFilename"), mutableJson);
|
|
155
231
|
}
|
|
156
232
|
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
233
|
+
if (Is.stringValue(network)) {
|
|
234
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.network"), network);
|
|
235
|
+
}
|
|
157
236
|
CLIDisplay.break();
|
|
158
237
|
setupVault();
|
|
159
238
|
const localIdentity = "local";
|
|
160
239
|
const vaultSeedId = "local-seed";
|
|
161
240
|
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
162
241
|
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
localPow: true
|
|
168
|
-
},
|
|
169
|
-
vaultSeedId
|
|
170
|
-
}
|
|
171
|
-
});
|
|
242
|
+
const nftConnector = setupNftConnector({ nodeEndpoint, network, vaultSeedId }, opts.connector);
|
|
243
|
+
if (Is.function(nftConnector.start)) {
|
|
244
|
+
await nftConnector.start(localIdentity);
|
|
245
|
+
}
|
|
172
246
|
const immutableJsonData = Is.stringValue(immutableJson)
|
|
173
247
|
? await CLIUtils.readJsonFile(immutableJson)
|
|
174
248
|
: undefined;
|
|
@@ -188,7 +262,7 @@ async function actionCommandNftMint(opts) {
|
|
|
188
262
|
CLIDisplay.task(I18n.formatMessage("commands.nft-mint.progress.mintingNft"));
|
|
189
263
|
CLIDisplay.break();
|
|
190
264
|
CLIDisplay.spinnerStart();
|
|
191
|
-
const nftId = await
|
|
265
|
+
const nftId = await nftConnector.mint(localIdentity, issuer, tag, immutableJsonData, mutableJsonData);
|
|
192
266
|
CLIDisplay.spinnerStop();
|
|
193
267
|
if (opts.console) {
|
|
194
268
|
CLIDisplay.value(I18n.formatMessage("commands.nft-mint.labels.nftId"), nftId);
|
|
@@ -200,7 +274,9 @@ async function actionCommandNftMint(opts) {
|
|
|
200
274
|
if (Is.stringValue(opts?.env)) {
|
|
201
275
|
await CLIUtils.writeEnvFile(opts.env, [`NFT_ID="${nftId}"`], opts.mergeEnv);
|
|
202
276
|
}
|
|
203
|
-
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"),
|
|
277
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), opts.connector === NftConnectorTypes.IotaRebased
|
|
278
|
+
? `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/object/${IotaRebasedNftUtils.nftIdToObjectId(nftId)}?network=${network}`
|
|
279
|
+
: `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaNftUtils.nftIdToAddress(nftId)}`);
|
|
204
280
|
CLIDisplay.break();
|
|
205
281
|
CLIDisplay.done();
|
|
206
282
|
}
|
|
@@ -226,7 +302,11 @@ function buildCommandNftResolve() {
|
|
|
226
302
|
mergeEnv: false
|
|
227
303
|
});
|
|
228
304
|
command
|
|
305
|
+
.addOption(new Option(I18n.formatMessage("commands.common.options.connector.param"), I18n.formatMessage("commands.common.options.connector.description"))
|
|
306
|
+
.choices(Object.values(NftConnectorTypes))
|
|
307
|
+
.default(NftConnectorTypes.Iota))
|
|
229
308
|
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
309
|
+
.option(I18n.formatMessage("commands.common.options.network.param"), I18n.formatMessage("commands.common.options.network.description"), "!NETWORK")
|
|
230
310
|
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
231
311
|
.action(actionCommandNftResolve);
|
|
232
312
|
return command;
|
|
@@ -235,29 +315,30 @@ function buildCommandNftResolve() {
|
|
|
235
315
|
* Action the nft resolve command.
|
|
236
316
|
* @param opts The options for the command.
|
|
237
317
|
* @param opts.id The id of the NFT to resolve in urn format.
|
|
318
|
+
* @param opts.connector The connector to perform the operations with.
|
|
238
319
|
* @param opts.node The node URL.
|
|
320
|
+
* @param opts.network The network to use for rebased connector.
|
|
239
321
|
* @param opts.explorer The explorer URL.
|
|
240
322
|
*/
|
|
241
323
|
async function actionCommandNftResolve(opts) {
|
|
242
324
|
const id = CLIParam.stringValue("id", opts.id);
|
|
243
325
|
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
326
|
+
const network = opts.connector === NftConnectorTypes.IotaRebased
|
|
327
|
+
? CLIParam.stringValue("network", opts.network)
|
|
328
|
+
: undefined;
|
|
244
329
|
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
245
330
|
CLIDisplay.value(I18n.formatMessage("commands.nft-resolve.labels.nftId"), id);
|
|
246
331
|
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
332
|
+
if (Is.stringValue(network)) {
|
|
333
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.network"), network);
|
|
334
|
+
}
|
|
247
335
|
CLIDisplay.break();
|
|
248
336
|
setupVault();
|
|
249
|
-
const
|
|
250
|
-
config: {
|
|
251
|
-
clientOptions: {
|
|
252
|
-
nodes: [nodeEndpoint],
|
|
253
|
-
localPow: true
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
});
|
|
337
|
+
const nftConnector = setupNftConnector({ nodeEndpoint, network }, opts.connector);
|
|
257
338
|
CLIDisplay.task(I18n.formatMessage("commands.nft-resolve.progress.resolvingNft"));
|
|
258
339
|
CLIDisplay.break();
|
|
259
340
|
CLIDisplay.spinnerStart();
|
|
260
|
-
const nft = await
|
|
341
|
+
const nft = await nftConnector.resolve(id);
|
|
261
342
|
CLIDisplay.spinnerStop();
|
|
262
343
|
if (opts.console) {
|
|
263
344
|
CLIDisplay.section(I18n.formatMessage("commands.nft-resolve.labels.nft"));
|
|
@@ -267,7 +348,9 @@ async function actionCommandNftResolve(opts) {
|
|
|
267
348
|
if (Is.stringValue(opts?.json)) {
|
|
268
349
|
await CLIUtils.writeJsonFile(opts.json, nft, opts.mergeJson);
|
|
269
350
|
}
|
|
270
|
-
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"),
|
|
351
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), opts.connector === NftConnectorTypes.IotaRebased
|
|
352
|
+
? `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/object/${IotaRebasedNftUtils.nftIdToObjectId(id)}?network=${network}`
|
|
353
|
+
: `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaNftUtils.nftIdToAddress(id)}`);
|
|
271
354
|
CLIDisplay.break();
|
|
272
355
|
CLIDisplay.done();
|
|
273
356
|
}
|
|
@@ -288,7 +371,11 @@ function buildCommandNftTransfer() {
|
|
|
288
371
|
.requiredOption(I18n.formatMessage("commands.nft-transfer.options.id.param"), I18n.formatMessage("commands.nft-transfer.options.id.description"))
|
|
289
372
|
.requiredOption(I18n.formatMessage("commands.nft-transfer.options.recipient.param"), I18n.formatMessage("commands.nft-transfer.options.recipient.description"));
|
|
290
373
|
command
|
|
374
|
+
.addOption(new Option(I18n.formatMessage("commands.common.options.connector.param"), I18n.formatMessage("commands.common.options.connector.description"))
|
|
375
|
+
.choices(Object.values(NftConnectorTypes))
|
|
376
|
+
.default(NftConnectorTypes.Iota))
|
|
291
377
|
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
378
|
+
.option(I18n.formatMessage("commands.common.options.network.param"), I18n.formatMessage("commands.common.options.network.description"), "!NETWORK")
|
|
292
379
|
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
293
380
|
.action(actionCommandNftTransfer);
|
|
294
381
|
return command;
|
|
@@ -299,39 +386,46 @@ function buildCommandNftTransfer() {
|
|
|
299
386
|
* @param opts.seed The seed required for signing by the issuer.
|
|
300
387
|
* @param opts.id The id of the NFT to transfer in urn format.
|
|
301
388
|
* @param opts.recipient The recipient address of the NFT.
|
|
389
|
+
* @param opts.connector The connector to perform the operations with.
|
|
302
390
|
* @param opts.node The node URL.
|
|
391
|
+
* @param opts.network The network to use for rebased connector.
|
|
303
392
|
* @param opts.explorer The explorer URL.
|
|
304
393
|
*/
|
|
305
394
|
async function actionCommandNftTransfer(opts) {
|
|
306
395
|
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
307
396
|
const id = CLIParam.stringValue("id", opts.id);
|
|
308
|
-
const recipient =
|
|
397
|
+
const recipient = opts.connector === NftConnectorTypes.IotaRebased
|
|
398
|
+
? Converter.bytesToHex(CLIParam.hex("recipient", opts.recipient), true)
|
|
399
|
+
: CLIParam.bech32("recipient", opts.recipient);
|
|
309
400
|
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
401
|
+
const network = opts.connector === NftConnectorTypes.IotaRebased
|
|
402
|
+
? CLIParam.stringValue("network", opts.network)
|
|
403
|
+
: undefined;
|
|
310
404
|
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
311
405
|
CLIDisplay.value(I18n.formatMessage("commands.nft-transfer.labels.nftId"), id);
|
|
312
406
|
CLIDisplay.value(I18n.formatMessage("commands.nft-transfer.labels.recipient"), recipient);
|
|
313
407
|
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
408
|
+
if (Is.stringValue(network)) {
|
|
409
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.network"), network);
|
|
410
|
+
}
|
|
314
411
|
CLIDisplay.break();
|
|
315
412
|
setupVault();
|
|
316
413
|
const localIdentity = "local";
|
|
317
414
|
const vaultSeedId = "local-seed";
|
|
318
415
|
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
319
416
|
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
localPow: true
|
|
325
|
-
},
|
|
326
|
-
vaultSeedId
|
|
327
|
-
}
|
|
328
|
-
});
|
|
417
|
+
const nftConnector = setupNftConnector({ nodeEndpoint, network, vaultSeedId }, opts.connector);
|
|
418
|
+
if (Is.function(nftConnector.start)) {
|
|
419
|
+
await nftConnector.start(localIdentity);
|
|
420
|
+
}
|
|
329
421
|
CLIDisplay.task(I18n.formatMessage("commands.nft-transfer.progress.transferringNft"));
|
|
330
422
|
CLIDisplay.break();
|
|
331
423
|
CLIDisplay.spinnerStart();
|
|
332
|
-
await
|
|
424
|
+
await nftConnector.transfer(localIdentity, id, recipient);
|
|
333
425
|
CLIDisplay.spinnerStop();
|
|
334
|
-
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"),
|
|
426
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), opts.connector === NftConnectorTypes.IotaRebased
|
|
427
|
+
? `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/object/${IotaRebasedNftUtils.nftIdToObjectId(id)}?network=${network}`
|
|
428
|
+
: `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaNftUtils.nftIdToAddress(id)}`);
|
|
335
429
|
CLIDisplay.break();
|
|
336
430
|
CLIDisplay.done();
|
|
337
431
|
}
|
|
@@ -354,7 +448,7 @@ class CLI extends CLIBase {
|
|
|
354
448
|
return this.execute({
|
|
355
449
|
title: "TWIN NFT",
|
|
356
450
|
appName: "twin-nft",
|
|
357
|
-
version: "0.0.1-next.
|
|
451
|
+
version: "0.0.1-next.15",
|
|
358
452
|
icon: "🌍",
|
|
359
453
|
supportsEnvFiles: true,
|
|
360
454
|
overrideOutputWidth: options?.overrideOutputWidth
|
|
@@ -378,4 +472,4 @@ class CLI extends CLIBase {
|
|
|
378
472
|
}
|
|
379
473
|
}
|
|
380
474
|
|
|
381
|
-
export { CLI, actionCommandNftBurn, actionCommandNftMint, actionCommandNftResolve, actionCommandNftTransfer, buildCommandNftBurn, buildCommandNftMint, buildCommandNftResolve, buildCommandNftTransfer };
|
|
475
|
+
export { CLI, NftConnectorTypes, actionCommandNftBurn, actionCommandNftMint, actionCommandNftResolve, actionCommandNftTransfer, buildCommandNftBurn, buildCommandNftMint, buildCommandNftResolve, buildCommandNftTransfer, setupNftConnector, setupVault };
|
package/dist/locales/en.json
CHANGED
|
@@ -201,6 +201,29 @@
|
|
|
201
201
|
"noKeyOrSigner": "No key or signer was provided for JWT creation",
|
|
202
202
|
"noKeyOrVerifier": "No key or verifier was provided for JWT creation"
|
|
203
203
|
},
|
|
204
|
+
"iotaRebasedNftConnector": {
|
|
205
|
+
"mintingFailed": "Minting the NFT failed",
|
|
206
|
+
"resolvingFailed": "Resolving the NFT failed",
|
|
207
|
+
"burningFailed": "Burning the NFT failed",
|
|
208
|
+
"transferFailed": "Transferring the NFT failed",
|
|
209
|
+
"updateFailed": "Updating the NFT failed",
|
|
210
|
+
"namespaceMismatch": "The namespace in the urn \"{id}\" does not match the namespace of the IOTA Rebased NFT connector \"{namespace}\"",
|
|
211
|
+
"failedToGetNftId": "Failed to get NFT ID from mint response",
|
|
212
|
+
"nftNotFound": "The NFT \"{nftId}\" was not found",
|
|
213
|
+
"startFailed": "Failed to start the IOTA Rebased NFT connector",
|
|
214
|
+
"deployTransactionFailed": "Deploying the contract failed with error: \"{error}\"",
|
|
215
|
+
"connectorNotStarted": "Please call start() before using this connector. Package ID: \"{packageId}\" is missing."
|
|
216
|
+
},
|
|
217
|
+
"iotaRebasedNftUtils": {
|
|
218
|
+
"invalidNftIdFormat": "The NFT ID \"{id}\" has an invalid format"
|
|
219
|
+
},
|
|
220
|
+
"iotaRebased": {
|
|
221
|
+
"insufficientFunds": "There were insufficient funds to complete the operation",
|
|
222
|
+
"packageNotFoundOnNetwork": "The package \"{packageId}\" was not found on the network",
|
|
223
|
+
"packageObjectError": "Failed to fetch the package object \"{packageId}\"",
|
|
224
|
+
"nftTransactionFailed": "The NFT transaction failed",
|
|
225
|
+
"addressNotFound": "The address is missing could not be found from the seed \"{address}\""
|
|
226
|
+
},
|
|
204
227
|
"entityStorageVaultConnector": {
|
|
205
228
|
"keyAlreadyExists": "The key \"{existingId}\" already exists in the vault",
|
|
206
229
|
"keyNotFound": "The key \"{notFoundId}\" was not found in the vault",
|
|
@@ -216,6 +239,12 @@
|
|
|
216
239
|
"iotaFaucetConnector": {
|
|
217
240
|
"fundingFailed": "Fund the address from faucet failed",
|
|
218
241
|
"insufficientFunds": "There were insufficient funds to complete the operation"
|
|
242
|
+
},
|
|
243
|
+
"iotaRebasedWalletConnector": {
|
|
244
|
+
"transferFailed": "The wallet transfer failed."
|
|
245
|
+
},
|
|
246
|
+
"iotaRebasedFaucetConnector": {
|
|
247
|
+
"fundingFailed": "Fund the address from faucet failed"
|
|
219
248
|
}
|
|
220
249
|
},
|
|
221
250
|
"errorNames": {
|
|
@@ -316,8 +345,8 @@
|
|
|
316
345
|
}
|
|
317
346
|
},
|
|
318
347
|
"address": {
|
|
319
|
-
"summary": "Create
|
|
320
|
-
"description": "Create a number of
|
|
348
|
+
"summary": "Create addresses and keys from the seed.",
|
|
349
|
+
"description": "Create a number of addresses and their associated key pairs from the seed.",
|
|
321
350
|
"options": {
|
|
322
351
|
"seed": {
|
|
323
352
|
"param": "--seed '<'seed'>'",
|
|
@@ -333,15 +362,15 @@
|
|
|
333
362
|
},
|
|
334
363
|
"account": {
|
|
335
364
|
"param": "--account '<'number'>'",
|
|
336
|
-
"description": "The account used to generate the
|
|
365
|
+
"description": "The account used to generate the addresses."
|
|
337
366
|
},
|
|
338
367
|
"hrp": {
|
|
339
368
|
"param": "--hrp '<'hrp'>'",
|
|
340
|
-
"description": "The human readable part
|
|
369
|
+
"description": "The human readable part for the addresses if generating bech32 format."
|
|
341
370
|
},
|
|
342
371
|
"coin": {
|
|
343
372
|
"param": "--coin '<'coin'>'",
|
|
344
|
-
"description": "The coin type used to generate the
|
|
373
|
+
"description": "The coin type used to generate the addresses."
|
|
345
374
|
},
|
|
346
375
|
"key-type": {
|
|
347
376
|
"param": "--key-type '<'type'>'",
|
|
@@ -376,7 +405,7 @@
|
|
|
376
405
|
"options": {
|
|
377
406
|
"address": {
|
|
378
407
|
"param": "--address '<'address'>'",
|
|
379
|
-
"description": "The address to fill from the faucet either
|
|
408
|
+
"description": "The address to fill from the faucet either bech32 or hex format, or start with ! to read environment variable."
|
|
380
409
|
},
|
|
381
410
|
"faucet": {
|
|
382
411
|
"param": "--faucet '<'url'>'",
|
|
@@ -420,15 +449,24 @@
|
|
|
420
449
|
"transferringFunds": "Transferring"
|
|
421
450
|
},
|
|
422
451
|
"labels": {
|
|
423
|
-
"destAddress": "Destination Address"
|
|
452
|
+
"destAddress": "Destination Address",
|
|
453
|
+
"amount": "Amount"
|
|
424
454
|
}
|
|
425
455
|
},
|
|
426
456
|
"common": {
|
|
427
457
|
"options": {
|
|
458
|
+
"connector": {
|
|
459
|
+
"param": "--connector '<'connector'>'",
|
|
460
|
+
"description": "The connector to use for the NFT operation."
|
|
461
|
+
},
|
|
428
462
|
"node": {
|
|
429
463
|
"param": "--node '<'url'>'",
|
|
430
464
|
"description": "The url for the node endpoint, or an environment variable name containing the url."
|
|
431
465
|
},
|
|
466
|
+
"network": {
|
|
467
|
+
"param": "--network '<'network'>'",
|
|
468
|
+
"description": "The network to use for the NFT operation."
|
|
469
|
+
},
|
|
432
470
|
"explorer": {
|
|
433
471
|
"param": "--explorer '<'url'>'",
|
|
434
472
|
"description": "The url for the explorer endpoint, or an environment variable name containing the url."
|
|
@@ -440,6 +478,8 @@
|
|
|
440
478
|
"node": "Node",
|
|
441
479
|
"explorer": "Explorer",
|
|
442
480
|
"explore": "Explore",
|
|
481
|
+
"connector": "Connector",
|
|
482
|
+
"network": "Network",
|
|
443
483
|
"did": "DID"
|
|
444
484
|
}
|
|
445
485
|
},
|
|
@@ -453,7 +493,7 @@
|
|
|
453
493
|
},
|
|
454
494
|
"issuer": {
|
|
455
495
|
"param": "--issuer '<'issuer'>'",
|
|
456
|
-
"description": "The
|
|
496
|
+
"description": "The address of the NFT issuer, or start with ! to read environment variable."
|
|
457
497
|
},
|
|
458
498
|
"tag": {
|
|
459
499
|
"param": "--tag '<'tag'>'",
|
|
@@ -508,7 +548,7 @@
|
|
|
508
548
|
},
|
|
509
549
|
"issuer": {
|
|
510
550
|
"param": "--issuer '<'issuer'>'",
|
|
511
|
-
"description": "The
|
|
551
|
+
"description": "The address of the NFT issuer, or start with ! to read environment variable."
|
|
512
552
|
},
|
|
513
553
|
"id": {
|
|
514
554
|
"param": "--id '<'id'>'",
|
|
@@ -537,7 +577,7 @@
|
|
|
537
577
|
},
|
|
538
578
|
"recipient": {
|
|
539
579
|
"param": "--recipient '<'recipient'>'",
|
|
540
|
-
"description": "The
|
|
580
|
+
"description": "The address of the NFT recipient, or start with ! to read environment variable."
|
|
541
581
|
}
|
|
542
582
|
},
|
|
543
583
|
"progress": {
|
|
@@ -551,5 +591,12 @@
|
|
|
551
591
|
},
|
|
552
592
|
"errorMessages": {
|
|
553
593
|
"fetch": "Fetch"
|
|
594
|
+
},
|
|
595
|
+
"info": {
|
|
596
|
+
"iotaRebasedNftConnector": {
|
|
597
|
+
"contractAlreadyDeployed": "Contract already deployed",
|
|
598
|
+
"contractDeploymentStarted": "Contract deployment started",
|
|
599
|
+
"contractDeploymentCompleted": "Contract deployment completed"
|
|
600
|
+
}
|
|
554
601
|
}
|
|
555
602
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import { NftConnectorTypes } from "../models/nftConnectorTypes";
|
|
2
3
|
/**
|
|
3
4
|
* Build the nft burn command for the CLI.
|
|
4
5
|
* @returns The command.
|
|
@@ -10,13 +11,17 @@ export declare function buildCommandNftBurn(): Command;
|
|
|
10
11
|
* @param opts.seed The seed required for signing by the issuer.
|
|
11
12
|
* @param opts.issuer The issuer address of the NFT.
|
|
12
13
|
* @param opts.id The id of the NFT to burn in urn format.
|
|
14
|
+
* @param opts.connector The connector to perform the operations with.
|
|
13
15
|
* @param opts.node The node URL.
|
|
16
|
+
* @param opts.network The network to use for rebased connector.
|
|
14
17
|
* @param opts.explorer The explorer URL.
|
|
15
18
|
*/
|
|
16
19
|
export declare function actionCommandNftBurn(opts: {
|
|
17
20
|
seed: string;
|
|
18
21
|
issuer: string;
|
|
19
22
|
id: string;
|
|
23
|
+
connector?: NftConnectorTypes;
|
|
20
24
|
node: string;
|
|
25
|
+
network?: string;
|
|
21
26
|
explorer: string;
|
|
22
27
|
}): Promise<void>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CliOutputOptions } from "@twin.org/cli-core";
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
+
import { NftConnectorTypes } from "../models/nftConnectorTypes";
|
|
3
4
|
/**
|
|
4
5
|
* Build the nft mint command for the CLI.
|
|
5
6
|
* @returns The command.
|
|
@@ -13,7 +14,9 @@ export declare function buildCommandNftMint(): Command;
|
|
|
13
14
|
* @param opts.tag The tag for the NFT.
|
|
14
15
|
* @param opts.immutableJson Filename of the immutable JSON data.
|
|
15
16
|
* @param opts.mutableJson Filename of the mutable JSON data.
|
|
17
|
+
* @param opts.connector The connector to perform the operations with.
|
|
16
18
|
* @param opts.node The node URL.
|
|
19
|
+
* @param opts.network The network to use for rebased connector.
|
|
17
20
|
* @param opts.explorer The explorer URL.
|
|
18
21
|
*/
|
|
19
22
|
export declare function actionCommandNftMint(opts: {
|
|
@@ -22,6 +25,8 @@ export declare function actionCommandNftMint(opts: {
|
|
|
22
25
|
tag: string;
|
|
23
26
|
immutableJson?: string;
|
|
24
27
|
mutableJson?: string;
|
|
28
|
+
connector?: NftConnectorTypes;
|
|
25
29
|
node: string;
|
|
30
|
+
network?: string;
|
|
26
31
|
explorer: string;
|
|
27
32
|
} & CliOutputOptions): Promise<void>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CliOutputOptions } from "@twin.org/cli-core";
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
+
import { NftConnectorTypes } from "../models/nftConnectorTypes";
|
|
3
4
|
/**
|
|
4
5
|
* Build the nft resolve command for the CLI.
|
|
5
6
|
* @returns The command.
|
|
@@ -9,11 +10,15 @@ export declare function buildCommandNftResolve(): Command;
|
|
|
9
10
|
* Action the nft resolve command.
|
|
10
11
|
* @param opts The options for the command.
|
|
11
12
|
* @param opts.id The id of the NFT to resolve in urn format.
|
|
13
|
+
* @param opts.connector The connector to perform the operations with.
|
|
12
14
|
* @param opts.node The node URL.
|
|
15
|
+
* @param opts.network The network to use for rebased connector.
|
|
13
16
|
* @param opts.explorer The explorer URL.
|
|
14
17
|
*/
|
|
15
18
|
export declare function actionCommandNftResolve(opts: {
|
|
16
19
|
id: string;
|
|
20
|
+
connector?: NftConnectorTypes;
|
|
17
21
|
node: string;
|
|
22
|
+
network?: string;
|
|
18
23
|
explorer: string;
|
|
19
24
|
} & CliOutputOptions): Promise<void>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import { NftConnectorTypes } from "../models/nftConnectorTypes";
|
|
2
3
|
/**
|
|
3
4
|
* Build the nft transfer command for the CLI.
|
|
4
5
|
* @returns The command.
|
|
@@ -10,13 +11,17 @@ export declare function buildCommandNftTransfer(): Command;
|
|
|
10
11
|
* @param opts.seed The seed required for signing by the issuer.
|
|
11
12
|
* @param opts.id The id of the NFT to transfer in urn format.
|
|
12
13
|
* @param opts.recipient The recipient address of the NFT.
|
|
14
|
+
* @param opts.connector The connector to perform the operations with.
|
|
13
15
|
* @param opts.node The node URL.
|
|
16
|
+
* @param opts.network The network to use for rebased connector.
|
|
14
17
|
* @param opts.explorer The explorer URL.
|
|
15
18
|
*/
|
|
16
19
|
export declare function actionCommandNftTransfer(opts: {
|
|
17
20
|
seed: string;
|
|
18
21
|
id: string;
|
|
19
22
|
recipient: string;
|
|
23
|
+
connector?: NftConnectorTypes;
|
|
20
24
|
node: string;
|
|
25
|
+
network?: string;
|
|
21
26
|
explorer: string;
|
|
22
27
|
}): Promise<void>;
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
+
import type { INftConnector } from "@twin.org/nft-models";
|
|
2
|
+
import { NftConnectorTypes } from "../models/nftConnectorTypes";
|
|
1
3
|
/**
|
|
2
4
|
* Setup the vault for use in the CLI commands.
|
|
3
5
|
*/
|
|
4
6
|
export declare function setupVault(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Setup the NFT connector for use in the CLI commands.
|
|
9
|
+
* @param options The options for the NFT connector.
|
|
10
|
+
* @param options.nodeEndpoint The node endpoint.
|
|
11
|
+
* @param options.network The network.
|
|
12
|
+
* @param options.vaultSeedId The vault seed ID.
|
|
13
|
+
* @param connector The connector to use.
|
|
14
|
+
* @returns The NFT connector.
|
|
15
|
+
*/
|
|
16
|
+
export declare function setupNftConnector(options: {
|
|
17
|
+
nodeEndpoint: string;
|
|
18
|
+
network?: string;
|
|
19
|
+
vaultSeedId?: string;
|
|
20
|
+
}, connector?: NftConnectorTypes): INftConnector;
|