@twin.org/dlt-iota 0.0.3-next.5 → 0.0.3-next.6
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/README.md +4 -6
- package/dist/es/index.js +2 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/iotaIdentityUtils.js +77 -0
- package/dist/es/iotaIdentityUtils.js.map +1 -0
- package/dist/es/models/IIotaControllerCapInfo.js +4 -0
- package/dist/es/models/IIotaControllerCapInfo.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/iotaIdentityUtils.d.ts +23 -0
- package/dist/types/models/IIotaControllerCapInfo.d.ts +16 -0
- package/docs/changelog.md +8 -1
- package/docs/examples.md +420 -1
- package/docs/reference/classes/IotaIdentityUtils.md +65 -0
- package/docs/reference/index.md +2 -0
- package/docs/reference/interfaces/IIotaConfig.md +0 -42
- package/docs/reference/interfaces/IIotaControllerCapInfo.md +22 -0
- package/docs/reference/interfaces/IIotaResponseOptions.md +0 -6
- package/locales/en.json +7 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TWIN DLT IOTA
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This package provides utilities for integrating applications with IOTA distributed ledger capabilities, including client construction, transaction submission, sponsored transaction support, and smart contract migration helpers. It is intended for services that need a reliable and repeatable approach to ledger operations without rebuilding common primitives.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,14 +8,12 @@ DLT helpers for use with IOTA.
|
|
|
8
8
|
npm install @twin.org/dlt-iota
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Docker
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
The simplest way to set up the testing environment using our unified container:
|
|
13
|
+
To perform testing of this component it may be necessary to launch a local instance to communicate with.
|
|
16
14
|
|
|
17
15
|
```shell
|
|
18
|
-
docker run -d --name twin-
|
|
16
|
+
docker run -d --name twin-dlt-iota -p 9527:9527 -p 6379:6379 -p 9184:9184 twinfoundation/twin-gas-station-test:latest
|
|
19
17
|
```
|
|
20
18
|
|
|
21
19
|
## Examples
|
package/dist/es/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright 2024 IOTA Stiftung.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
3
|
export * from "./iota.js";
|
|
4
|
+
export * from "./iotaIdentityUtils.js";
|
|
4
5
|
export * from "./iotaSmartContractUtils.js";
|
|
5
6
|
export * from "./models/IAdminCapFields.js";
|
|
6
7
|
export * from "./models/IContractData.js";
|
|
@@ -10,6 +11,7 @@ export * from "./models/IGasStationExecuteResponse.js";
|
|
|
10
11
|
export * from "./models/IGasStationReserveGasResponse.js";
|
|
11
12
|
export * from "./models/IGasStationReserveGasResult.js";
|
|
12
13
|
export * from "./models/IIotaClient.js";
|
|
14
|
+
export * from "./models/IIotaControllerCapInfo.js";
|
|
13
15
|
export * from "./models/IIotaTransaction.js";
|
|
14
16
|
export * from "./models/IIotaTransactionBlockResponse.js";
|
|
15
17
|
export * from "./models/IIotaConfig.js";
|
package/dist/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,WAAW,CAAC;AAC1B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./iota.js\";\nexport * from \"./iotaSmartContractUtils.js\";\nexport * from \"./models/IAdminCapFields.js\";\nexport * from \"./models/IContractData.js\";\nexport * from \"./models/IGasReservationResult.js\";\nexport * from \"./models/IGasStationConfig.js\";\nexport * from \"./models/IGasStationExecuteResponse.js\";\nexport * from \"./models/IGasStationReserveGasResponse.js\";\nexport * from \"./models/IGasStationReserveGasResult.js\";\nexport * from \"./models/IIotaClient.js\";\nexport * from \"./models/IIotaTransaction.js\";\nexport * from \"./models/IIotaTransactionBlockResponse.js\";\nexport * from \"./models/IIotaConfig.js\";\nexport * from \"./models/IIotaDryRun.js\";\nexport * from \"./models/IIotaResponseOptions.js\";\nexport * from \"./models/IMigrationStateFields.js\";\nexport * from \"./models/ISmartContractDeployments.js\";\nexport * from \"./models/ISmartContractObject.js\";\nexport * from \"./models/networkTypes.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,WAAW,CAAC;AAC1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yBAAyB,CAAC;AACxC,cAAc,oCAAoC,CAAC;AACnD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./iota.js\";\nexport * from \"./iotaIdentityUtils.js\";\nexport * from \"./iotaSmartContractUtils.js\";\nexport * from \"./models/IAdminCapFields.js\";\nexport * from \"./models/IContractData.js\";\nexport * from \"./models/IGasReservationResult.js\";\nexport * from \"./models/IGasStationConfig.js\";\nexport * from \"./models/IGasStationExecuteResponse.js\";\nexport * from \"./models/IGasStationReserveGasResponse.js\";\nexport * from \"./models/IGasStationReserveGasResult.js\";\nexport * from \"./models/IIotaClient.js\";\nexport * from \"./models/IIotaControllerCapInfo.js\";\nexport * from \"./models/IIotaTransaction.js\";\nexport * from \"./models/IIotaTransactionBlockResponse.js\";\nexport * from \"./models/IIotaConfig.js\";\nexport * from \"./models/IIotaDryRun.js\";\nexport * from \"./models/IIotaResponseOptions.js\";\nexport * from \"./models/IMigrationStateFields.js\";\nexport * from \"./models/ISmartContractDeployments.js\";\nexport * from \"./models/ISmartContractObject.js\";\nexport * from \"./models/networkTypes.js\";\n"]}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import { IdentityClient, IdentityClientReadOnly, OnChainIdentity } from "@iota/identity-wasm/node/index.js";
|
|
4
|
+
import { Ed25519PublicKey } from "@iota/iota-sdk/keypairs/ed25519";
|
|
5
|
+
import { GeneralError, Guards, Is, NotFoundError } from "@twin.org/core";
|
|
6
|
+
import { Iota } from "./iota.js";
|
|
7
|
+
/**
|
|
8
|
+
* Utility class for resolving IOTA Identity on-chain objects required by
|
|
9
|
+
* the NFT mint_with_identity() Move contract function.
|
|
10
|
+
*/
|
|
11
|
+
export class IotaIdentityUtils {
|
|
12
|
+
/**
|
|
13
|
+
* Runtime name for the class.
|
|
14
|
+
*/
|
|
15
|
+
static CLASS_NAME = "IotaIdentityUtils";
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the on-chain object IDs for an identity and its controller token.
|
|
18
|
+
* Returns the IDs needed to call mint_with_identity() on the NFT Move contract.
|
|
19
|
+
* @param identityId The DID of the identity (e.g. "did:iota:testnet:0x...").
|
|
20
|
+
* @param controllerAddress The on-chain address of the controller wallet.
|
|
21
|
+
* @param client The IOTA client instance.
|
|
22
|
+
* @returns The identity object ID and controller token object ID.
|
|
23
|
+
* @throws NotFoundError if the identity does not exist on-chain.
|
|
24
|
+
* @throws GeneralError if the identity has been deleted or the controller token is not found.
|
|
25
|
+
*/
|
|
26
|
+
static async getControllerCapInfo(identityId, controllerAddress, client) {
|
|
27
|
+
Guards.stringValue(IotaIdentityUtils.CLASS_NAME, "identityId", identityId);
|
|
28
|
+
Guards.stringValue(IotaIdentityUtils.CLASS_NAME, "controllerAddress", controllerAddress);
|
|
29
|
+
// Extract the Object ID from the DID — last colon-delimited segment, prefixed with 0x.
|
|
30
|
+
// IOTA DIDs have the format did:iota:<network>:<hex> where <hex> has no 0x prefix.
|
|
31
|
+
const idParts = identityId.split(":");
|
|
32
|
+
const identityObjectId = `0x${idParts[idParts.length - 1]}`;
|
|
33
|
+
let onChain;
|
|
34
|
+
let controllerToken;
|
|
35
|
+
try {
|
|
36
|
+
// Both are IotaClient@1.11.0 but TypeScript resolves them from different module
|
|
37
|
+
// entry points (dist/esm vs dist/cjs). The protected `transport` field causes a
|
|
38
|
+
// class-compatibility failure even though the runtime types are identical.
|
|
39
|
+
// Casting through the function's own parameter type keeps this refactor-safe.
|
|
40
|
+
const identityClientReadOnly = await IdentityClientReadOnly.create(client);
|
|
41
|
+
// getControllerTokenForAddress requires IdentityClient even though the operation is
|
|
42
|
+
// read-only — the signer is never called, only the embedded CoreClientReadOnly is
|
|
43
|
+
// used. TransactionSigner is a structural interface, so a minimal object literal
|
|
44
|
+
// that satisfies its shape avoids importing the heavyweight JWK store machinery.
|
|
45
|
+
const noOpSigner = {
|
|
46
|
+
sign: async (_txData) => {
|
|
47
|
+
throw new GeneralError(IotaIdentityUtils.CLASS_NAME, "unexpectedSignerCall", undefined);
|
|
48
|
+
},
|
|
49
|
+
publicKey: async () => new Ed25519PublicKey(new Uint8Array(32)),
|
|
50
|
+
iotaPublicKeyBytes: async () => new Uint8Array(32),
|
|
51
|
+
keyId: () => ""
|
|
52
|
+
};
|
|
53
|
+
const identityClient = await IdentityClient.create(identityClientReadOnly, noOpSigner);
|
|
54
|
+
onChain = await OnChainIdentity.getById(identityObjectId, identityClient);
|
|
55
|
+
if (!Is.undefined(onChain) && !onChain.hasDeletedDid()) {
|
|
56
|
+
controllerToken = await onChain.getControllerTokenForAddress(controllerAddress, identityClient);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new GeneralError(IotaIdentityUtils.CLASS_NAME, "getControllerCapInfoFailed", undefined, Iota.extractPayloadError(error));
|
|
61
|
+
}
|
|
62
|
+
if (Is.undefined(onChain)) {
|
|
63
|
+
throw new NotFoundError(IotaIdentityUtils.CLASS_NAME, "identityNotFound", identityId);
|
|
64
|
+
}
|
|
65
|
+
if (onChain.hasDeletedDid()) {
|
|
66
|
+
throw new GeneralError(IotaIdentityUtils.CLASS_NAME, "identityDeleted", { identityId });
|
|
67
|
+
}
|
|
68
|
+
if (Is.undefined(controllerToken)) {
|
|
69
|
+
throw new NotFoundError(IotaIdentityUtils.CLASS_NAME, "controllerTokenNotFound", identityId);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
identityObjectId,
|
|
73
|
+
controllerCapObjectId: controllerToken.id()
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=iotaIdentityUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iotaIdentityUtils.js","sourceRoot":"","sources":["../../src/iotaIdentityUtils.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tIdentityClient,\n\tIdentityClientReadOnly,\n\tOnChainIdentity\n} from \"@iota/identity-wasm/node/index.js\";\nimport type { IotaClient } from \"@iota/iota-sdk/client\";\nimport type { PublicKey } from \"@iota/iota-sdk/cryptography\";\nimport { Ed25519PublicKey } from \"@iota/iota-sdk/keypairs/ed25519\";\nimport { GeneralError, Guards, Is, NotFoundError } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { Iota } from \"./iota.js\";\nimport type { IIotaControllerCapInfo } from \"./models/IIotaControllerCapInfo.js\";\n\n/**\n * Utility class for resolving IOTA Identity on-chain objects required by\n * the NFT mint_with_identity() Move contract function.\n */\nexport class IotaIdentityUtils {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<IotaIdentityUtils>();\n\n\t/**\n\t * Resolve the on-chain object IDs for an identity and its controller token.\n\t * Returns the IDs needed to call mint_with_identity() on the NFT Move contract.\n\t * @param identityId The DID of the identity (e.g. \"did:iota:testnet:0x...\").\n\t * @param controllerAddress The on-chain address of the controller wallet.\n\t * @param client The IOTA client instance.\n\t * @returns The identity object ID and controller token object ID.\n\t * @throws NotFoundError if the identity does not exist on-chain.\n\t * @throws GeneralError if the identity has been deleted or the controller token is not found.\n\t */\n\tpublic static async getControllerCapInfo(\n\t\tidentityId: string,\n\t\tcontrollerAddress: string,\n\t\tclient: IotaClient\n\t): Promise<IIotaControllerCapInfo> {\n\t\tGuards.stringValue(IotaIdentityUtils.CLASS_NAME, nameof(identityId), identityId);\n\t\tGuards.stringValue(IotaIdentityUtils.CLASS_NAME, nameof(controllerAddress), controllerAddress);\n\n\t\t// Extract the Object ID from the DID — last colon-delimited segment, prefixed with 0x.\n\t\t// IOTA DIDs have the format did:iota:<network>:<hex> where <hex> has no 0x prefix.\n\t\tconst idParts = identityId.split(\":\");\n\t\tconst identityObjectId = `0x${idParts[idParts.length - 1]}`;\n\n\t\tlet onChain: OnChainIdentity | undefined;\n\t\tlet controllerToken: Awaited<ReturnType<OnChainIdentity[\"getControllerTokenForAddress\"]>>;\n\n\t\ttry {\n\t\t\t// Both are IotaClient@1.11.0 but TypeScript resolves them from different module\n\t\t\t// entry points (dist/esm vs dist/cjs). The protected `transport` field causes a\n\t\t\t// class-compatibility failure even though the runtime types are identical.\n\t\t\t// Casting through the function's own parameter type keeps this refactor-safe.\n\t\t\tconst identityClientReadOnly = await IdentityClientReadOnly.create(\n\t\t\t\tclient as unknown as Parameters<(typeof IdentityClientReadOnly)[\"create\"]>[0]\n\t\t\t);\n\n\t\t\t// getControllerTokenForAddress requires IdentityClient even though the operation is\n\t\t\t// read-only — the signer is never called, only the embedded CoreClientReadOnly is\n\t\t\t// used. TransactionSigner is a structural interface, so a minimal object literal\n\t\t\t// that satisfies its shape avoids importing the heavyweight JWK store machinery.\n\t\t\tconst noOpSigner = {\n\t\t\t\tsign: async (_txData: Uint8Array): Promise<string> => {\n\t\t\t\t\tthrow new GeneralError(IotaIdentityUtils.CLASS_NAME, \"unexpectedSignerCall\", undefined);\n\t\t\t\t},\n\t\t\t\tpublicKey: async (): Promise<PublicKey> => new Ed25519PublicKey(new Uint8Array(32)),\n\t\t\t\tiotaPublicKeyBytes: async (): Promise<Uint8Array> => new Uint8Array(32),\n\t\t\t\tkeyId: (): string => \"\"\n\t\t\t};\n\t\t\tconst identityClient = await IdentityClient.create(identityClientReadOnly, noOpSigner);\n\n\t\t\tonChain = await OnChainIdentity.getById(identityObjectId, identityClient);\n\t\t\tif (!Is.undefined(onChain) && !onChain.hasDeletedDid()) {\n\t\t\t\tcontrollerToken = await onChain.getControllerTokenForAddress(\n\t\t\t\t\tcontrollerAddress,\n\t\t\t\t\tidentityClient\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIotaIdentityUtils.CLASS_NAME,\n\t\t\t\t\"getControllerCapInfoFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\n\t\tif (Is.undefined(onChain)) {\n\t\t\tthrow new NotFoundError(IotaIdentityUtils.CLASS_NAME, \"identityNotFound\", identityId);\n\t\t}\n\n\t\tif (onChain.hasDeletedDid()) {\n\t\t\tthrow new GeneralError(IotaIdentityUtils.CLASS_NAME, \"identityDeleted\", { identityId });\n\t\t}\n\n\t\tif (Is.undefined(controllerToken)) {\n\t\t\tthrow new NotFoundError(IotaIdentityUtils.CLASS_NAME, \"controllerTokenNotFound\", identityId);\n\t\t}\n\n\t\treturn {\n\t\t\tidentityObjectId,\n\t\t\tcontrollerCapObjectId: controllerToken.id()\n\t\t};\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IIotaControllerCapInfo.js","sourceRoot":"","sources":["../../../src/models/IIotaControllerCapInfo.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * On-chain object IDs needed to call mint_with_identity() on the NFT Move contract.\n */\nexport interface IIotaControllerCapInfo {\n\t/**\n\t * The on-chain Object ID of the Identity Move object (hex string, e.g. \"0x...\").\n\t * Used as the Identity argument in mint_with_identity().\n\t */\n\tidentityObjectId: string;\n\n\t/**\n\t * The on-chain Object ID of the ControllerToken Move object (hex string, e.g. \"0x...\").\n\t * Proves that the controller address controls identityObjectId.\n\t * Used as the ControllerCap argument in mint_with_identity().\n\t */\n\tcontrollerCapObjectId: string;\n}\n"]}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from "./iota.js";
|
|
2
|
+
export * from "./iotaIdentityUtils.js";
|
|
2
3
|
export * from "./iotaSmartContractUtils.js";
|
|
3
4
|
export * from "./models/IAdminCapFields.js";
|
|
4
5
|
export * from "./models/IContractData.js";
|
|
@@ -8,6 +9,7 @@ export * from "./models/IGasStationExecuteResponse.js";
|
|
|
8
9
|
export * from "./models/IGasStationReserveGasResponse.js";
|
|
9
10
|
export * from "./models/IGasStationReserveGasResult.js";
|
|
10
11
|
export * from "./models/IIotaClient.js";
|
|
12
|
+
export * from "./models/IIotaControllerCapInfo.js";
|
|
11
13
|
export * from "./models/IIotaTransaction.js";
|
|
12
14
|
export * from "./models/IIotaTransactionBlockResponse.js";
|
|
13
15
|
export * from "./models/IIotaConfig.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IotaClient } from "@iota/iota-sdk/client";
|
|
2
|
+
import type { IIotaControllerCapInfo } from "./models/IIotaControllerCapInfo.js";
|
|
3
|
+
/**
|
|
4
|
+
* Utility class for resolving IOTA Identity on-chain objects required by
|
|
5
|
+
* the NFT mint_with_identity() Move contract function.
|
|
6
|
+
*/
|
|
7
|
+
export declare class IotaIdentityUtils {
|
|
8
|
+
/**
|
|
9
|
+
* Runtime name for the class.
|
|
10
|
+
*/
|
|
11
|
+
static readonly CLASS_NAME: string;
|
|
12
|
+
/**
|
|
13
|
+
* Resolve the on-chain object IDs for an identity and its controller token.
|
|
14
|
+
* Returns the IDs needed to call mint_with_identity() on the NFT Move contract.
|
|
15
|
+
* @param identityId The DID of the identity (e.g. "did:iota:testnet:0x...").
|
|
16
|
+
* @param controllerAddress The on-chain address of the controller wallet.
|
|
17
|
+
* @param client The IOTA client instance.
|
|
18
|
+
* @returns The identity object ID and controller token object ID.
|
|
19
|
+
* @throws NotFoundError if the identity does not exist on-chain.
|
|
20
|
+
* @throws GeneralError if the identity has been deleted or the controller token is not found.
|
|
21
|
+
*/
|
|
22
|
+
static getControllerCapInfo(identityId: string, controllerAddress: string, client: IotaClient): Promise<IIotaControllerCapInfo>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* On-chain object IDs needed to call mint_with_identity() on the NFT Move contract.
|
|
3
|
+
*/
|
|
4
|
+
export interface IIotaControllerCapInfo {
|
|
5
|
+
/**
|
|
6
|
+
* The on-chain Object ID of the Identity Move object (hex string, e.g. "0x...").
|
|
7
|
+
* Used as the Identity argument in mint_with_identity().
|
|
8
|
+
*/
|
|
9
|
+
identityObjectId: string;
|
|
10
|
+
/**
|
|
11
|
+
* The on-chain Object ID of the ControllerToken Move object (hex string, e.g. "0x...").
|
|
12
|
+
* Proves that the controller address controls identityObjectId.
|
|
13
|
+
* Used as the ControllerCap argument in mint_with_identity().
|
|
14
|
+
*/
|
|
15
|
+
controllerCapObjectId: string;
|
|
16
|
+
}
|
package/docs/changelog.md
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.0.3-next.6](https://github.com/twinfoundation/dlt/compare/dlt-iota-v0.0.3-next.5...dlt-iota-v0.0.3-next.6) (2026-03-12)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add IotaIdentityUtils to resolve IOTA identity controller cap info ([#57](https://github.com/twinfoundation/dlt/issues/57)) ([f15281a](https://github.com/twinfoundation/dlt/commit/f15281af3b2812bde5130a1813f9c0143f1462bf))
|
|
2
9
|
|
|
3
10
|
## [0.0.3-next.5](https://github.com/twinfoundation/dlt/compare/dlt-iota-v0.0.3-next.4...dlt-iota-v0.0.3-next.5) (2026-03-03)
|
|
4
11
|
|
package/docs/examples.md
CHANGED
|
@@ -1 +1,420 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DLT IOTA Examples
|
|
2
|
+
|
|
3
|
+
These snippets show practical ways to configure clients, derive addresses, post transactions, and manage contract migration flows in production-style integrations.
|
|
4
|
+
|
|
5
|
+
## Iota
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Iota, NetworkTypes, type IIotaConfig } from '@twin.org/dlt-iota';
|
|
9
|
+
|
|
10
|
+
const config: IIotaConfig = {
|
|
11
|
+
network: NetworkTypes.Testnet,
|
|
12
|
+
clientOptions: {
|
|
13
|
+
url: 'https://api.testnet.iota.cafe'
|
|
14
|
+
},
|
|
15
|
+
inclusionTimeoutSeconds: 45
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
Iota.populateConfig(config);
|
|
19
|
+
const client = Iota.createClient(config);
|
|
20
|
+
|
|
21
|
+
console.log(config.coinType); // 4218
|
|
22
|
+
console.log(config.vaultMnemonicId); // mnemonic
|
|
23
|
+
console.log(client !== undefined); // true
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { Bip39 } from '@twin.org/crypto';
|
|
28
|
+
import { Iota } from '@twin.org/dlt-iota';
|
|
29
|
+
|
|
30
|
+
const mnemonic =
|
|
31
|
+
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
|
32
|
+
const seed = Bip39.mnemonicToSeed(mnemonic);
|
|
33
|
+
|
|
34
|
+
const addresses = Iota.getAddresses(seed, Iota.DEFAULT_COIN_TYPE, 0, 0, 3);
|
|
35
|
+
const keyPair = Iota.getKeyPair(seed, Iota.DEFAULT_COIN_TYPE, 0, 0);
|
|
36
|
+
const found = Iota.findAddress(50, Iota.DEFAULT_COIN_TYPE, seed, addresses[0]);
|
|
37
|
+
|
|
38
|
+
console.log(addresses.length); // 3
|
|
39
|
+
console.log(found.address === addresses[0]); // true
|
|
40
|
+
console.log(keyPair.publicKey.length > 0); // true
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { Converter } from '@twin.org/core';
|
|
45
|
+
import { Iota, type IIotaConfig } from '@twin.org/dlt-iota';
|
|
46
|
+
import type { IVaultConnector } from '@twin.org/vault-models';
|
|
47
|
+
|
|
48
|
+
const config: IIotaConfig = {
|
|
49
|
+
clientOptions: {
|
|
50
|
+
url: 'https://api.testnet.iota.cafe'
|
|
51
|
+
},
|
|
52
|
+
vaultMnemonicId: 'deployment-mnemonic',
|
|
53
|
+
vaultSeedId: 'deployment-seed'
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const vaultConnector: IVaultConnector = {
|
|
57
|
+
async getSecret<T>(key: string): Promise<T> {
|
|
58
|
+
if (key.endsWith('/deployment-seed')) {
|
|
59
|
+
return Converter.bytesToBase64(new Uint8Array(32).fill(7)) as T;
|
|
60
|
+
}
|
|
61
|
+
if (key.endsWith('/deployment-mnemonic')) {
|
|
62
|
+
const value =
|
|
63
|
+
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
|
64
|
+
return value as T;
|
|
65
|
+
}
|
|
66
|
+
throw new Error('Unknown key');
|
|
67
|
+
}
|
|
68
|
+
} as IVaultConnector;
|
|
69
|
+
|
|
70
|
+
const mnemonicKey = Iota.buildMnemonicKey('deployer', config.vaultMnemonicId);
|
|
71
|
+
const seedKey = Iota.buildSeedKey('deployer', config.vaultSeedId);
|
|
72
|
+
const seed = await Iota.getSeed(config, vaultConnector, 'deployer');
|
|
73
|
+
|
|
74
|
+
console.log(mnemonicKey); // deployer/deployment-mnemonic
|
|
75
|
+
console.log(seedKey); // deployer/deployment-seed
|
|
76
|
+
console.log(seed.length); // 32
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import {
|
|
81
|
+
Iota,
|
|
82
|
+
type IIotaClient,
|
|
83
|
+
type IIotaConfig,
|
|
84
|
+
type IIotaTransaction,
|
|
85
|
+
type IIotaTransactionBlockResponse
|
|
86
|
+
} from '@twin.org/dlt-iota';
|
|
87
|
+
import type { IVaultConnector } from '@twin.org/vault-models';
|
|
88
|
+
|
|
89
|
+
const config: IIotaConfig = {
|
|
90
|
+
clientOptions: {
|
|
91
|
+
url: 'https://api.testnet.iota.cafe'
|
|
92
|
+
},
|
|
93
|
+
waitForConfirmation: true
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const tx = Iota.createTransaction();
|
|
97
|
+
tx.setSender('0xabc123');
|
|
98
|
+
|
|
99
|
+
const responseOptions = {
|
|
100
|
+
waitForConfirmation: true,
|
|
101
|
+
dryRunLabel: 'transfer_iota'
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const client = {} as IIotaClient;
|
|
105
|
+
const vaultConnector = {} as IVaultConnector;
|
|
106
|
+
|
|
107
|
+
const result: IIotaTransactionBlockResponse = await Iota.prepareAndPostTransaction(
|
|
108
|
+
config,
|
|
109
|
+
vaultConnector,
|
|
110
|
+
undefined,
|
|
111
|
+
'deployer',
|
|
112
|
+
client,
|
|
113
|
+
'0xabc123',
|
|
114
|
+
tx as IIotaTransaction,
|
|
115
|
+
responseOptions
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
await Iota.waitForTransactionConfirmation(client, result.digest, config, {
|
|
119
|
+
showEffects: true,
|
|
120
|
+
showEvents: true,
|
|
121
|
+
showObjectChanges: true
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
console.log(typeof result.digest === 'string'); // true
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import {
|
|
129
|
+
Iota,
|
|
130
|
+
type IIotaClient,
|
|
131
|
+
type IIotaConfig,
|
|
132
|
+
type IIotaTransaction,
|
|
133
|
+
type IIotaTransactionBlockResponse
|
|
134
|
+
} from '@twin.org/dlt-iota';
|
|
135
|
+
import type { IVaultConnector } from '@twin.org/vault-models';
|
|
136
|
+
|
|
137
|
+
const config: IIotaConfig = {
|
|
138
|
+
clientOptions: {
|
|
139
|
+
url: 'https://api.testnet.iota.cafe'
|
|
140
|
+
},
|
|
141
|
+
gasBudget: 80_000_000,
|
|
142
|
+
gasStation: {
|
|
143
|
+
gasStationUrl: 'https://gasstation.testnet.example',
|
|
144
|
+
gasStationAuthToken: 'replace-with-token'
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const client = {} as IIotaClient;
|
|
149
|
+
const vaultConnector = {} as IVaultConnector;
|
|
150
|
+
const tx = Iota.createTransaction();
|
|
151
|
+
|
|
152
|
+
const gasReservation = await Iota.reserveGas(config, config.gasBudget ?? 50_000_000);
|
|
153
|
+
const txBytes = new Uint8Array([1, 2, 3, 4]);
|
|
154
|
+
const userSignature = 'base64-signature';
|
|
155
|
+
|
|
156
|
+
const sponsoredResult = await Iota.executeGasStationTransaction(
|
|
157
|
+
config,
|
|
158
|
+
gasReservation.reservationId,
|
|
159
|
+
txBytes,
|
|
160
|
+
userSignature
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const finalResult: IIotaTransactionBlockResponse =
|
|
164
|
+
await Iota.executeAndConfirmGasStationTransaction(
|
|
165
|
+
config,
|
|
166
|
+
client,
|
|
167
|
+
gasReservation.reservationId,
|
|
168
|
+
txBytes,
|
|
169
|
+
userSignature,
|
|
170
|
+
{
|
|
171
|
+
waitForConfirmation: true
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
const postedResult = await Iota.prepareAndPostGasStationTransaction(
|
|
176
|
+
config,
|
|
177
|
+
vaultConnector,
|
|
178
|
+
'deployer',
|
|
179
|
+
client,
|
|
180
|
+
'0xabc123',
|
|
181
|
+
tx as IIotaTransaction
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
console.log(gasReservation.reservationId > 0); // true
|
|
185
|
+
console.log(sponsoredResult.confirmedLocalExecution); // true
|
|
186
|
+
console.log(typeof finalResult.digest === 'string'); // true
|
|
187
|
+
console.log(typeof postedResult.digest === 'string'); // true
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import { Iota, type IIotaClient, type IIotaConfig } from '@twin.org/dlt-iota';
|
|
192
|
+
import type { ILoggingComponent } from '@twin.org/logging-models';
|
|
193
|
+
|
|
194
|
+
const config: IIotaConfig = {
|
|
195
|
+
clientOptions: {
|
|
196
|
+
url: 'https://api.testnet.iota.cafe'
|
|
197
|
+
},
|
|
198
|
+
inclusionTimeoutSeconds: 30
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const client = {} as IIotaClient;
|
|
202
|
+
const tx = Iota.createTransaction();
|
|
203
|
+
const logging = {} as ILoggingComponent;
|
|
204
|
+
|
|
205
|
+
const packageExists = await Iota.packageExistsOnNetwork(client, '0x2');
|
|
206
|
+
const dryRun = await Iota.dryRunTransaction(client, logging, tx, '0xabc123', 'mint_token');
|
|
207
|
+
const isAbort = Iota.isAbortError(new Error('MoveAbort: abort code: 17'), 17);
|
|
208
|
+
const parsedError = Iota.extractPayloadError({ code: 'InsufficientGas' });
|
|
209
|
+
|
|
210
|
+
console.log(packageExists); // true
|
|
211
|
+
console.log(dryRun.status); // success
|
|
212
|
+
console.log(isAbort); // true
|
|
213
|
+
console.log(parsedError.name); // General
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import {
|
|
218
|
+
Iota,
|
|
219
|
+
type IIotaClient,
|
|
220
|
+
type IIotaConfig,
|
|
221
|
+
type IIotaTransactionBlockResponse
|
|
222
|
+
} from '@twin.org/dlt-iota';
|
|
223
|
+
import type { IVaultConnector } from '@twin.org/vault-models';
|
|
224
|
+
|
|
225
|
+
const config: IIotaConfig = {
|
|
226
|
+
clientOptions: {
|
|
227
|
+
url: 'https://api.testnet.iota.cafe'
|
|
228
|
+
},
|
|
229
|
+
gasStation: {
|
|
230
|
+
gasStationUrl: 'https://gasstation.testnet.example',
|
|
231
|
+
gasStationAuthToken: 'replace-with-token'
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const client = {} as IIotaClient;
|
|
236
|
+
const vaultConnector = {} as IVaultConnector;
|
|
237
|
+
|
|
238
|
+
const transferResult: IIotaTransactionBlockResponse = await Iota.prepareAndPostValueTransaction(
|
|
239
|
+
config,
|
|
240
|
+
vaultConnector,
|
|
241
|
+
undefined,
|
|
242
|
+
'deployer',
|
|
243
|
+
client,
|
|
244
|
+
'0xabc123',
|
|
245
|
+
5_000_000n,
|
|
246
|
+
'0xdef456'
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
console.log(typeof transferResult.digest === 'string'); // true
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## IotaSmartContractUtils
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import {
|
|
256
|
+
IotaSmartContractUtils,
|
|
257
|
+
NetworkTypes,
|
|
258
|
+
type IIotaConfig,
|
|
259
|
+
type ISmartContractDeployments
|
|
260
|
+
} from '@twin.org/dlt-iota';
|
|
261
|
+
import type { IotaClient } from '@iota/iota-sdk/client';
|
|
262
|
+
import type { ILoggingComponent } from '@twin.org/logging-models';
|
|
263
|
+
import type { IVaultConnector } from '@twin.org/vault-models';
|
|
264
|
+
import type { IWalletConnector } from '@twin.org/wallet-models';
|
|
265
|
+
|
|
266
|
+
const config: IIotaConfig = {
|
|
267
|
+
network: NetworkTypes.Testnet,
|
|
268
|
+
clientOptions: {
|
|
269
|
+
url: 'https://api.testnet.iota.cafe'
|
|
270
|
+
},
|
|
271
|
+
enableCostLogging: true
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const deploymentConfig: ISmartContractDeployments = {
|
|
275
|
+
testnet: {
|
|
276
|
+
packageId: '0x111',
|
|
277
|
+
deployedPackageId: '0x111',
|
|
278
|
+
migrationStateId: '0x222',
|
|
279
|
+
packageBytecode: 'base64'
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const client = {} as IotaClient;
|
|
284
|
+
const vaultConnector = {} as IVaultConnector;
|
|
285
|
+
const walletConnector = {} as IWalletConnector;
|
|
286
|
+
const logging = {} as ILoggingComponent;
|
|
287
|
+
|
|
288
|
+
await IotaSmartContractUtils.enableMigration(
|
|
289
|
+
config,
|
|
290
|
+
client,
|
|
291
|
+
vaultConnector,
|
|
292
|
+
walletConnector,
|
|
293
|
+
logging,
|
|
294
|
+
80_000_000,
|
|
295
|
+
'controller',
|
|
296
|
+
'nft',
|
|
297
|
+
'0x111',
|
|
298
|
+
deploymentConfig
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
await IotaSmartContractUtils.disableMigration(
|
|
302
|
+
config,
|
|
303
|
+
client,
|
|
304
|
+
vaultConnector,
|
|
305
|
+
walletConnector,
|
|
306
|
+
logging,
|
|
307
|
+
80_000_000,
|
|
308
|
+
'controller',
|
|
309
|
+
'nft',
|
|
310
|
+
'0x111',
|
|
311
|
+
deploymentConfig
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
console.log(IotaSmartContractUtils.CLASS_NAME); // IotaSmartContractUtils
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import {
|
|
319
|
+
IotaSmartContractUtils,
|
|
320
|
+
NetworkTypes,
|
|
321
|
+
type IIotaConfig,
|
|
322
|
+
type ISmartContractDeployments
|
|
323
|
+
} from '@twin.org/dlt-iota';
|
|
324
|
+
import type { IotaClient } from '@iota/iota-sdk/client';
|
|
325
|
+
import type { ILoggingComponent } from '@twin.org/logging-models';
|
|
326
|
+
import type { IVaultConnector } from '@twin.org/vault-models';
|
|
327
|
+
import type { IWalletConnector } from '@twin.org/wallet-models';
|
|
328
|
+
|
|
329
|
+
const config: IIotaConfig = {
|
|
330
|
+
network: NetworkTypes.Testnet,
|
|
331
|
+
clientOptions: {
|
|
332
|
+
url: 'https://api.testnet.iota.cafe'
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
const deploymentConfig: ISmartContractDeployments = {
|
|
337
|
+
testnet: {
|
|
338
|
+
packageId: '0x111',
|
|
339
|
+
deployedPackageId: '0x111',
|
|
340
|
+
migrationStateId: '0x222',
|
|
341
|
+
packageBytecode: 'base64'
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const client = {} as IotaClient;
|
|
346
|
+
const vaultConnector = {} as IVaultConnector;
|
|
347
|
+
const walletConnector = {} as IWalletConnector;
|
|
348
|
+
const logging = {} as ILoggingComponent;
|
|
349
|
+
|
|
350
|
+
await IotaSmartContractUtils.migrateSmartContract(
|
|
351
|
+
config,
|
|
352
|
+
client,
|
|
353
|
+
vaultConnector,
|
|
354
|
+
walletConnector,
|
|
355
|
+
logging,
|
|
356
|
+
90_000_000,
|
|
357
|
+
'controller',
|
|
358
|
+
'0x999',
|
|
359
|
+
'nft',
|
|
360
|
+
'0x111',
|
|
361
|
+
deploymentConfig
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
const migrationActive = await IotaSmartContractUtils.isMigrationActive(
|
|
365
|
+
config,
|
|
366
|
+
client,
|
|
367
|
+
'nft',
|
|
368
|
+
'0x111',
|
|
369
|
+
deploymentConfig,
|
|
370
|
+
'controller',
|
|
371
|
+
walletConnector
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
console.log(migrationActive); // true
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import { IotaSmartContractUtils, NetworkTypes, type IIotaConfig } from '@twin.org/dlt-iota';
|
|
379
|
+
import type { IotaClient } from '@iota/iota-sdk/client';
|
|
380
|
+
import type { IWalletConnector } from '@twin.org/wallet-models';
|
|
381
|
+
|
|
382
|
+
type ContractObjectFields = {
|
|
383
|
+
fields: {
|
|
384
|
+
version: string;
|
|
385
|
+
};
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const config: IIotaConfig = {
|
|
389
|
+
network: NetworkTypes.Testnet,
|
|
390
|
+
clientOptions: {
|
|
391
|
+
url: 'https://api.testnet.iota.cafe'
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
const client = {} as IotaClient;
|
|
396
|
+
const walletConnector = {} as IWalletConnector;
|
|
397
|
+
|
|
398
|
+
const currentVersion = await IotaSmartContractUtils.getCurrentContractVersion(
|
|
399
|
+
config,
|
|
400
|
+
client,
|
|
401
|
+
'nft',
|
|
402
|
+
'0x111',
|
|
403
|
+
'controller',
|
|
404
|
+
walletConnector
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
const isCompatible = await IotaSmartContractUtils.validateObjectVersion<ContractObjectFields>(
|
|
408
|
+
config,
|
|
409
|
+
client,
|
|
410
|
+
'nft',
|
|
411
|
+
'0x111',
|
|
412
|
+
'controller',
|
|
413
|
+
'0x777',
|
|
414
|
+
walletConnector,
|
|
415
|
+
content => Number(content.fields.version)
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
console.log(currentVersion >= 1); // true
|
|
419
|
+
console.log(isCompatible); // true
|
|
420
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Class: IotaIdentityUtils
|
|
2
|
+
|
|
3
|
+
Utility class for resolving IOTA Identity on-chain objects required by
|
|
4
|
+
the NFT mint_with_identity() Move contract function.
|
|
5
|
+
|
|
6
|
+
## Constructors
|
|
7
|
+
|
|
8
|
+
### Constructor
|
|
9
|
+
|
|
10
|
+
> **new IotaIdentityUtils**(): `IotaIdentityUtils`
|
|
11
|
+
|
|
12
|
+
#### Returns
|
|
13
|
+
|
|
14
|
+
`IotaIdentityUtils`
|
|
15
|
+
|
|
16
|
+
## Properties
|
|
17
|
+
|
|
18
|
+
### CLASS\_NAME
|
|
19
|
+
|
|
20
|
+
> `readonly` `static` **CLASS\_NAME**: `string`
|
|
21
|
+
|
|
22
|
+
Runtime name for the class.
|
|
23
|
+
|
|
24
|
+
## Methods
|
|
25
|
+
|
|
26
|
+
### getControllerCapInfo()
|
|
27
|
+
|
|
28
|
+
> `static` **getControllerCapInfo**(`identityId`, `controllerAddress`, `client`): `Promise`\<[`IIotaControllerCapInfo`](../interfaces/IIotaControllerCapInfo.md)\>
|
|
29
|
+
|
|
30
|
+
Resolve the on-chain object IDs for an identity and its controller token.
|
|
31
|
+
Returns the IDs needed to call mint_with_identity() on the NFT Move contract.
|
|
32
|
+
|
|
33
|
+
#### Parameters
|
|
34
|
+
|
|
35
|
+
##### identityId
|
|
36
|
+
|
|
37
|
+
`string`
|
|
38
|
+
|
|
39
|
+
The DID of the identity (e.g. "did:iota:testnet:0x...").
|
|
40
|
+
|
|
41
|
+
##### controllerAddress
|
|
42
|
+
|
|
43
|
+
`string`
|
|
44
|
+
|
|
45
|
+
The on-chain address of the controller wallet.
|
|
46
|
+
|
|
47
|
+
##### client
|
|
48
|
+
|
|
49
|
+
`IotaClient`
|
|
50
|
+
|
|
51
|
+
The IOTA client instance.
|
|
52
|
+
|
|
53
|
+
#### Returns
|
|
54
|
+
|
|
55
|
+
`Promise`\<[`IIotaControllerCapInfo`](../interfaces/IIotaControllerCapInfo.md)\>
|
|
56
|
+
|
|
57
|
+
The identity object ID and controller token object ID.
|
|
58
|
+
|
|
59
|
+
#### Throws
|
|
60
|
+
|
|
61
|
+
NotFoundError if the identity does not exist on-chain.
|
|
62
|
+
|
|
63
|
+
#### Throws
|
|
64
|
+
|
|
65
|
+
GeneralError if the identity has been deleted or the controller token is not found.
|
package/docs/reference/index.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
## Classes
|
|
4
4
|
|
|
5
5
|
- [Iota](classes/Iota.md)
|
|
6
|
+
- [IotaIdentityUtils](classes/IotaIdentityUtils.md)
|
|
6
7
|
- [IotaSmartContractUtils](classes/IotaSmartContractUtils.md)
|
|
7
8
|
|
|
8
9
|
## Interfaces
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
- [IGasStationReserveGasResponse](interfaces/IGasStationReserveGasResponse.md)
|
|
16
17
|
- [IGasStationReserveGasResult](interfaces/IGasStationReserveGasResult.md)
|
|
17
18
|
- [IIotaConfig](interfaces/IIotaConfig.md)
|
|
19
|
+
- [IIotaControllerCapInfo](interfaces/IIotaControllerCapInfo.md)
|
|
18
20
|
- [IIotaDryRun](interfaces/IIotaDryRun.md)
|
|
19
21
|
- [IIotaResponseOptions](interfaces/IIotaResponseOptions.md)
|
|
20
22
|
- [IMigrationStateFields](interfaces/IMigrationStateFields.md)
|
|
@@ -26,12 +26,6 @@ The network the operations are being performed on.
|
|
|
26
26
|
|
|
27
27
|
The id of the entry in the vault containing the mnemonic.
|
|
28
28
|
|
|
29
|
-
#### Default
|
|
30
|
-
|
|
31
|
-
```ts
|
|
32
|
-
mnemonic
|
|
33
|
-
```
|
|
34
|
-
|
|
35
29
|
***
|
|
36
30
|
|
|
37
31
|
### vaultSeedId?
|
|
@@ -40,12 +34,6 @@ mnemonic
|
|
|
40
34
|
|
|
41
35
|
The id of the entry in the vault containing the seed.
|
|
42
36
|
|
|
43
|
-
#### Default
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
seed
|
|
47
|
-
```
|
|
48
|
-
|
|
49
37
|
***
|
|
50
38
|
|
|
51
39
|
### coinType?
|
|
@@ -54,12 +42,6 @@ seed
|
|
|
54
42
|
|
|
55
43
|
The coin type.
|
|
56
44
|
|
|
57
|
-
#### Default
|
|
58
|
-
|
|
59
|
-
```ts
|
|
60
|
-
IOTA 4218
|
|
61
|
-
```
|
|
62
|
-
|
|
63
45
|
***
|
|
64
46
|
|
|
65
47
|
### maxAddressScanRange?
|
|
@@ -68,12 +50,6 @@ IOTA 4218
|
|
|
68
50
|
|
|
69
51
|
The maximum range to scan for addresses.
|
|
70
52
|
|
|
71
|
-
#### Default
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
1000
|
|
75
|
-
```
|
|
76
|
-
|
|
77
53
|
***
|
|
78
54
|
|
|
79
55
|
### inclusionTimeoutSeconds?
|
|
@@ -82,12 +58,6 @@ The maximum range to scan for addresses.
|
|
|
82
58
|
|
|
83
59
|
The length of time to wait for the inclusion of a transaction in seconds.
|
|
84
60
|
|
|
85
|
-
#### Default
|
|
86
|
-
|
|
87
|
-
```ts
|
|
88
|
-
60
|
|
89
|
-
```
|
|
90
|
-
|
|
91
61
|
***
|
|
92
62
|
|
|
93
63
|
### gasStation?
|
|
@@ -105,12 +75,6 @@ If provided, transactions will be processed through the gas station.
|
|
|
105
75
|
|
|
106
76
|
The default gas budget for all transactions (including sponsored and direct).
|
|
107
77
|
|
|
108
|
-
#### Default
|
|
109
|
-
|
|
110
|
-
```ts
|
|
111
|
-
50000000
|
|
112
|
-
```
|
|
113
|
-
|
|
114
78
|
***
|
|
115
79
|
|
|
116
80
|
### enableCostLogging?
|
|
@@ -118,9 +82,3 @@ The default gas budget for all transactions (including sponsored and direct).
|
|
|
118
82
|
> `optional` **enableCostLogging**: `boolean`
|
|
119
83
|
|
|
120
84
|
Enable cost logging for transactions.
|
|
121
|
-
|
|
122
|
-
#### Default
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
false
|
|
126
|
-
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Interface: IIotaControllerCapInfo
|
|
2
|
+
|
|
3
|
+
On-chain object IDs needed to call mint_with_identity() on the NFT Move contract.
|
|
4
|
+
|
|
5
|
+
## Properties
|
|
6
|
+
|
|
7
|
+
### identityObjectId
|
|
8
|
+
|
|
9
|
+
> **identityObjectId**: `string`
|
|
10
|
+
|
|
11
|
+
The on-chain Object ID of the Identity Move object (hex string, e.g. "0x...").
|
|
12
|
+
Used as the Identity argument in mint_with_identity().
|
|
13
|
+
|
|
14
|
+
***
|
|
15
|
+
|
|
16
|
+
### controllerCapObjectId
|
|
17
|
+
|
|
18
|
+
> **controllerCapObjectId**: `string`
|
|
19
|
+
|
|
20
|
+
The on-chain Object ID of the ControllerToken Move object (hex string, e.g. "0x...").
|
|
21
|
+
Proves that the controller address controls identityObjectId.
|
|
22
|
+
Used as the ControllerCap argument in mint_with_identity().
|
package/locales/en.json
CHANGED
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
"gasStationTransactionFailed": "The gas station transaction failed",
|
|
11
11
|
"dryRunFailed": "The dry run execution failed"
|
|
12
12
|
},
|
|
13
|
+
"iotaIdentityUtils": {
|
|
14
|
+
"getControllerCapInfoFailed": "Getting the controller capability info for the identity failed",
|
|
15
|
+
"identityNotFound": "The identity could not be found \"{notFoundId}\"",
|
|
16
|
+
"identityDeleted": "The identity \"{identityId}\" has been deleted and cannot be used for minting",
|
|
17
|
+
"controllerTokenNotFound": "No controller token found for the identity \"{notFoundId}\" with the provided controller address",
|
|
18
|
+
"unexpectedSignerCall": "The no-op signer was unexpectedly called during a read-only identity lookup"
|
|
19
|
+
},
|
|
13
20
|
"iotaSmartContractUtils": {
|
|
14
21
|
"migrationFailed": "Smart contract migration failed",
|
|
15
22
|
"migrateSmartContractFailed": "Failed to migrate smart contract for object \"{objectId}\"",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/dlt-iota",
|
|
3
|
-
"version": "0.0.3-next.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.3-next.6",
|
|
4
|
+
"description": "IOTA distributed ledger utilities for clients, transactions, and contract operations.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/twinfoundation/dlt.git",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@iota/bcs": "1.5.0",
|
|
18
|
+
"@iota/identity-wasm": "1.9.2-beta.1",
|
|
18
19
|
"@iota/iota-sdk": "1.11.0",
|
|
19
20
|
"@twin.org/core": "next",
|
|
20
21
|
"@twin.org/crypto": "next",
|