@twin.org/dlt-iota 0.0.2-next.8 → 0.0.3-next.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.
- package/README.md +1 -81
- package/dist/es/index.js +19 -0
- package/dist/es/index.js.map +1 -0
- package/dist/es/iota.js +508 -0
- package/dist/es/iota.js.map +1 -0
- package/dist/es/iotaSmartContractUtils.js +413 -0
- package/dist/es/iotaSmartContractUtils.js.map +1 -0
- package/dist/es/models/IAdminCapFields.js +4 -0
- package/dist/es/models/IAdminCapFields.js.map +1 -0
- package/dist/es/models/IContractData.js +4 -0
- package/dist/es/models/IContractData.js.map +1 -0
- package/dist/es/models/IGasReservationResult.js +2 -0
- package/dist/es/models/IGasReservationResult.js.map +1 -0
- package/dist/es/models/IGasStationConfig.js +4 -0
- package/dist/es/models/IGasStationConfig.js.map +1 -0
- package/dist/es/models/IGasStationExecuteResponse.js +4 -0
- package/dist/es/models/IGasStationExecuteResponse.js.map +1 -0
- package/dist/es/models/IGasStationReserveGasResponse.js +2 -0
- package/dist/es/models/IGasStationReserveGasResponse.js.map +1 -0
- package/dist/es/models/IGasStationReserveGasResult.js +2 -0
- package/dist/es/models/IGasStationReserveGasResult.js.map +1 -0
- package/dist/es/models/IIotaConfig.js +2 -0
- package/dist/es/models/IIotaConfig.js.map +1 -0
- package/dist/es/models/IIotaDryRun.js +2 -0
- package/dist/es/models/IIotaDryRun.js.map +1 -0
- package/dist/es/models/IIotaResponseOptions.js +2 -0
- package/dist/es/models/IIotaResponseOptions.js.map +1 -0
- package/dist/es/models/IMigrationStateFields.js +4 -0
- package/dist/es/models/IMigrationStateFields.js.map +1 -0
- package/dist/es/models/ISmartContractDeployments.js +2 -0
- package/dist/es/models/ISmartContractDeployments.js.map +1 -0
- package/dist/es/models/ISmartContractObject.js +4 -0
- package/dist/es/models/ISmartContractObject.js.map +1 -0
- package/dist/es/models/networkTypes.js +21 -0
- package/dist/es/models/networkTypes.js.map +1 -0
- package/dist/types/index.d.ts +16 -16
- package/dist/types/iota.d.ts +8 -4
- package/dist/types/iotaSmartContractUtils.d.ts +2 -2
- package/dist/types/models/IContractData.d.ts +4 -0
- package/dist/types/models/IGasStationReserveGasResponse.d.ts +1 -1
- package/dist/types/models/IIotaConfig.d.ts +1 -1
- package/dist/types/models/ISmartContractDeployments.d.ts +2 -2
- package/docs/changelog.md +51 -0
- package/docs/reference/classes/Iota.md +11 -3
- package/docs/reference/classes/IotaSmartContractUtils.md +3 -3
- package/docs/reference/interfaces/IContractData.md +8 -0
- package/docs/reference/interfaces/IGasStationExecuteResponse.md +1 -1
- package/docs/reference/interfaces/IGasStationReserveGasResponse.md +1 -1
- package/locales/en.json +6 -2
- package/package.json +21 -12
- package/dist/cjs/index.cjs +0 -946
- package/dist/esm/index.mjs +0 -942
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iota.js","sourceRoot":"","sources":["../../src/iota.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { IotaClient, type IotaTransactionBlockResponse } from \"@iota/iota-sdk/client\";\nimport { Ed25519Keypair } from \"@iota/iota-sdk/keypairs/ed25519\";\nimport { Transaction } from \"@iota/iota-sdk/transactions\";\nimport {\n\tBaseError,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tIs,\n\tStringHelper,\n\ttype IError\n} from \"@twin.org/core\";\nimport { Bip39, Bip44, KeyType } from \"@twin.org/crypto\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { IVaultConnector } from \"@twin.org/vault-models\";\nimport { FetchHelper, HttpMethod } from \"@twin.org/web\";\nimport type { IGasReservationResult } from \"./models/IGasReservationResult.js\";\nimport type { IGasStationConfig } from \"./models/IGasStationConfig.js\";\nimport type { IGasStationExecuteResponse } from \"./models/IGasStationExecuteResponse.js\";\nimport type { IGasStationReserveGasResponse } from \"./models/IGasStationReserveGasResponse.js\";\nimport type { IIotaConfig } from \"./models/IIotaConfig.js\";\nimport type { IIotaDryRun } from \"./models/IIotaDryRun.js\";\nimport type { IIotaResponseOptions } from \"./models/IIotaResponseOptions.js\";\n\n/**\n * Class for performing operations on IOTA.\n */\nexport class Iota {\n\t/**\n\t * Default name for the mnemonic secret.\n\t */\n\tpublic static readonly DEFAULT_MNEMONIC_SECRET_NAME: string = \"mnemonic\";\n\n\t/**\n\t * Default name for the seed secret.\n\t */\n\tpublic static readonly DEFAULT_SEED_SECRET_NAME: string = \"seed\";\n\n\t/**\n\t * Default coin type.\n\t */\n\tpublic static readonly DEFAULT_COIN_TYPE: number = 4218;\n\n\t/**\n\t * Default scan range.\n\t */\n\tpublic static readonly DEFAULT_SCAN_RANGE: number = 1000;\n\n\t/**\n\t * Default inclusion timeout.\n\t */\n\tpublic static readonly DEFAULT_INCLUSION_TIMEOUT: number = 60;\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Iota>();\n\n\t/**\n\t * Create a new IOTA client.\n\t * @param config The configuration.\n\t * @returns The client instance.\n\t */\n\tpublic static createClient(config: IIotaConfig): IotaClient {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.clientOptions), config.clientOptions);\n\t\tGuards.string(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\n\t\treturn new IotaClient(config.clientOptions);\n\t}\n\n\t/**\n\t * Create configuration using defaults where necessary.\n\t * @param config The configuration to populate.\n\t */\n\tpublic static populateConfig(config: IIotaConfig): void {\n\t\tGuards.object<IIotaConfig[\"clientOptions\"]>(\n\t\t\tIota.CLASS_NAME,\n\t\t\tnameof(config.clientOptions),\n\t\t\tconfig.clientOptions\n\t\t);\n\n\t\tconfig.vaultMnemonicId ??= Iota.DEFAULT_MNEMONIC_SECRET_NAME;\n\t\tconfig.vaultSeedId ??= Iota.DEFAULT_SEED_SECRET_NAME;\n\t\tconfig.coinType ??= Iota.DEFAULT_COIN_TYPE;\n\t\tconfig.inclusionTimeoutSeconds ??= Iota.DEFAULT_INCLUSION_TIMEOUT;\n\t}\n\n\t/**\n\t * Get addresses for the identity.\n\t * @param seed The seed to use for generating addresses.\n\t * @param coinType The coin type to use.\n\t * @param accountIndex The account index to get the addresses for.\n\t * @param startAddressIndex The start index for the addresses.\n\t * @param count The number of addresses to generate.\n\t * @param isInternal Whether the addresses are internal.\n\t * @returns The list of addresses.\n\t */\n\tpublic static getAddresses(\n\t\tseed: Uint8Array,\n\t\tcoinType: number,\n\t\taccountIndex: number,\n\t\tstartAddressIndex: number,\n\t\tcount: number,\n\t\tisInternal?: boolean\n\t): string[] {\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(coinType), coinType);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(accountIndex), accountIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(startAddressIndex), startAddressIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(count), count);\n\n\t\tconst addresses: string[] = [];\n\n\t\tfor (let i = startAddressIndex; i < startAddressIndex + count; i++) {\n\t\t\t// Derive the keypair using the seed\n\t\t\tconst keyPair = Bip44.keyPair(\n\t\t\t\tseed,\n\t\t\t\tKeyType.Ed25519,\n\t\t\t\tcoinType ?? Iota.DEFAULT_COIN_TYPE,\n\t\t\t\taccountIndex,\n\t\t\t\tisInternal ?? false,\n\t\t\t\ti\n\t\t\t);\n\n\t\t\tconst keypair = Ed25519Keypair.fromSecretKey(keyPair.privateKey);\n\t\t\taddresses.push(keypair.getPublicKey().toIotaAddress());\n\t\t}\n\n\t\treturn addresses;\n\t}\n\n\t/**\n\t * Get a key pair for the specified index.\n\t * @param seed The seed to use for generating the key pair.\n\t * @param coinType The coin type to use.\n\t * @param accountIndex The account index to get the key pair for.\n\t * @param addressIndex The address index to get the key pair for.\n\t * @param isInternal Whether the address is internal.\n\t * @returns The key pair containing private key and public key.\n\t */\n\tpublic static getKeyPair(\n\t\tseed: Uint8Array,\n\t\tcoinType: number,\n\t\taccountIndex: number,\n\t\taddressIndex: number,\n\t\tisInternal?: boolean\n\t): {\n\t\tprivateKey: Uint8Array;\n\t\tpublicKey: Uint8Array;\n\t} {\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(coinType), coinType);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(accountIndex), accountIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(addressIndex), addressIndex);\n\n\t\tconst keyPair = Bip44.keyPair(\n\t\t\tseed,\n\t\t\tKeyType.Ed25519,\n\t\t\tcoinType ?? Iota.DEFAULT_COIN_TYPE,\n\t\t\taccountIndex,\n\t\t\tisInternal ?? false,\n\t\t\taddressIndex\n\t\t);\n\n\t\treturn keyPair;\n\t}\n\n\t/**\n\t * Prepare and post a transaction.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param logging The logging component.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param source The source address.\n\t * @param amount The amount to transfer.\n\t * @param recipient The recipient address.\n\t * @param options The transaction options.\n\t * @returns The transaction result.\n\t */\n\tpublic static async prepareAndPostValueTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tidentity: string,\n\t\tclient: IotaClient,\n\t\tsource: string,\n\t\tamount: bigint,\n\t\trecipient: string,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IotaTransactionBlockResponse> {\n\t\ttry {\n\t\t\tconst txb = new Transaction();\n\t\t\tconst [coin] = txb.splitCoins(txb.gas, [txb.pure.u64(amount)]);\n\t\t\ttxb.transferObjects([coin], txb.pure.address(recipient));\n\n\t\t\t// Check if gas station configuration is present\n\t\t\tif (Is.object<IGasStationConfig>(config.gasStation)) {\n\t\t\t\treturn await Iota.prepareAndPostGasStationTransaction(\n\t\t\t\t\tconfig,\n\t\t\t\t\tvaultConnector,\n\t\t\t\t\tidentity,\n\t\t\t\t\tclient,\n\t\t\t\t\tsource,\n\t\t\t\t\ttxb\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst result = await Iota.prepareAndPostTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tlogging,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\tsource,\n\t\t\t\ttxb,\n\t\t\t\toptions\n\t\t\t);\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"valueTransactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Prepare and post a transaction.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param logging The logging component.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param owner The owner of the address.\n\t * @param transaction The transaction to execute.\n\t * @param options The transaction options.\n\t * @returns The transaction response.\n\t */\n\tpublic static async prepareAndPostTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tidentity: string,\n\t\tclient: IotaClient,\n\t\towner: string,\n\t\ttransaction: Transaction,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IotaTransactionBlockResponse> {\n\t\t// Check if gas station configuration is present\n\t\tif (Is.object<IGasStationConfig>(config.gasStation)) {\n\t\t\treturn Iota.prepareAndPostGasStationTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\towner,\n\t\t\t\ttransaction,\n\t\t\t\toptions\n\t\t\t);\n\t\t}\n\n\t\t// Traditional transaction flow\n\t\t// Dry run the transaction if cost logging is enabled to get the gas and storage costs\n\t\tif (Is.stringValue(options?.dryRunLabel)) {\n\t\t\tawait Iota.dryRunTransaction(client, logging, transaction, owner, options.dryRunLabel);\n\t\t}\n\n\t\tconst seed = await Iota.getSeed(config, vaultConnector, identity);\n\t\tconst addressKeyPair = Iota.findAddress(\n\t\t\tconfig.maxAddressScanRange ?? Iota.DEFAULT_SCAN_RANGE,\n\t\t\tconfig.coinType ?? Iota.DEFAULT_COIN_TYPE,\n\t\t\tseed,\n\t\t\towner\n\t\t);\n\t\tconst keypair = Ed25519Keypair.fromSecretKey(addressKeyPair.privateKey);\n\n\t\ttry {\n\t\t\tconst response = await client.signAndExecuteTransaction({\n\t\t\t\ttransaction,\n\t\t\t\tsigner: keypair,\n\t\t\t\trequestType: \"WaitForLocalExecution\",\n\t\t\t\toptions: {\n\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (options?.waitForConfirmation ?? true) {\n\t\t\t\t// Wait for transaction to be indexed and available over API\n\t\t\t\tconst confirmedTransaction = await Iota.waitForTransactionConfirmation(\n\t\t\t\t\tclient,\n\t\t\t\t\tresponse.digest,\n\t\t\t\t\tconfig,\n\t\t\t\t\t{\n\t\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\treturn confirmedTransaction;\n\t\t\t}\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"transactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get the seed from the vault.\n\t * @param config The configuration to use.\n\t * @param vaultConnector The vault connector to use.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @returns The seed.\n\t */\n\tpublic static async getSeed(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tidentity: string\n\t): Promise<Uint8Array> {\n\t\ttry {\n\t\t\tconst seedBase64 = await vaultConnector.getSecret<string>(\n\t\t\t\tIota.buildSeedKey(identity, config.vaultSeedId)\n\t\t\t);\n\t\t\treturn Converter.base64ToBytes(seedBase64);\n\t\t} catch {}\n\n\t\tconst mnemonic = await vaultConnector.getSecret<string>(\n\t\t\tIota.buildMnemonicKey(identity, config.vaultMnemonicId)\n\t\t);\n\n\t\treturn Bip39.mnemonicToSeed(mnemonic);\n\t}\n\n\t/**\n\t * Find the address in the seed.\n\t * @param maxScanRange The maximum range to scan.\n\t * @param coinType The coin type to use.\n\t * @param seed The seed to use.\n\t * @param address The address to find.\n\t * @returns The address key pair.\n\t * @throws Error if the address is not found.\n\t */\n\tpublic static findAddress(\n\t\tmaxScanRange: number,\n\t\tcoinType: number,\n\t\tseed: Uint8Array,\n\t\taddress: string\n\t): {\n\t\taddress: string;\n\t\tprivateKey: Uint8Array;\n\t\tpublicKey: Uint8Array;\n\t} {\n\t\tfor (let i = 0; i < maxScanRange; i++) {\n\t\t\tconst addressKeyPair = Bip44.address(seed, KeyType.Ed25519, coinType, 0, false, i);\n\n\t\t\tif (addressKeyPair.address === address) {\n\t\t\t\treturn addressKeyPair;\n\t\t\t}\n\t\t}\n\n\t\tthrow new GeneralError(Iota.CLASS_NAME, \"addressNotFound\", { address });\n\t}\n\n\t/**\n\t * Extract error from SDK payload.\n\t * Errors from the IOTA SDK are usually not JSON strings but objects.\n\t * @param error The error to extract.\n\t * @returns The extracted error.\n\t */\n\tpublic static extractPayloadError(error: unknown): IError {\n\t\tif (Is.object<{ code?: string; message?: string; inner?: unknown; cause?: unknown }>(error)) {\n\t\t\tif (!Is.empty(error.inner)) {\n\t\t\t\terror.inner = Iota.extractPayloadError(error.inner);\n\t\t\t}\n\t\t\tif (!Is.empty(error.cause)) {\n\t\t\t\terror.cause = Iota.extractPayloadError(error.cause);\n\t\t\t}\n\n\t\t\tif (error.code === \"InsufficientGas\") {\n\t\t\t\treturn new GeneralError(Iota.CLASS_NAME, \"insufficientFunds\");\n\t\t\t} else if (error.message?.startsWith(\"ErrorObject\")) {\n\t\t\t\tconst msg = /message: \"(.*)\"/.exec(error.message);\n\t\t\t\tif (msg && msg.length > 1) {\n\t\t\t\t\terror = msg[1];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst baseError = BaseError.fromError(error);\n\t\tif (baseError.name === \"Base\" && !Is.stringValue(baseError.source)) {\n\t\t\tbaseError.name = \"IOTA\";\n\t\t\tbaseError.source = Iota.CLASS_NAME;\n\t\t}\n\t\treturn baseError;\n\t}\n\n\t/**\n\t * Get the key for storing the mnemonic.\n\t * @param identity The identity to use.\n\t * @param vaultMnemonicId The mnemonic ID to use.\n\t * @returns The mnemonic key.\n\t */\n\tpublic static buildMnemonicKey(identity: string, vaultMnemonicId?: string): string {\n\t\treturn `${identity}/${vaultMnemonicId ?? Iota.DEFAULT_MNEMONIC_SECRET_NAME}`;\n\t}\n\n\t/**\n\t * Get the key for storing the seed.\n\t * @param identity The identity to use.\n\t * @param vaultSeedId The seed ID to use.\n\t * @returns The seed key.\n\t */\n\tpublic static buildSeedKey(identity: string, vaultSeedId?: string): string {\n\t\treturn `${identity}/${vaultSeedId ?? Iota.DEFAULT_SEED_SECRET_NAME}`;\n\t}\n\n\t/**\n\t * Check if the package exists on the network.\n\t * @param client The client to use.\n\t * @param packageId The package ID to check.\n\t * @returns True if the package exists, false otherwise.\n\t */\n\tpublic static async packageExistsOnNetwork(\n\t\tclient: IotaClient,\n\t\tpackageId: string\n\t): Promise<boolean> {\n\t\ttry {\n\t\t\tconst packageObject = await client.getObject({\n\t\t\t\tid: packageId,\n\t\t\t\toptions: {\n\t\t\t\t\tshowType: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (\"error\" in packageObject) {\n\t\t\t\tif (packageObject?.error?.code === \"notExists\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"packageObjectError\", {\n\t\t\t\t\tpackageId,\n\t\t\t\t\terror: packageObject.error\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"packageNotFoundOnNetwork\",\n\t\t\t\t{\n\t\t\t\t\tpackageId\n\t\t\t\t},\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Dry run a transaction and log the results.\n\t * @param client The IOTA client.\n\t * @param logging The logging component.\n\t * @param txb The transaction to dry run.\n\t * @param sender The sender address.\n\t * @param operation The operation to log.\n\t * @returns void.\n\t */\n\tpublic static async dryRunTransaction(\n\t\tclient: IotaClient,\n\t\tlogging: ILoggingComponent | undefined,\n\t\ttxb: Transaction,\n\t\tsender: string,\n\t\toperation: string\n\t): Promise<IIotaDryRun> {\n\t\ttry {\n\t\t\ttxb.setSender(sender);\n\n\t\t\tconst builtTx = await txb.build({\n\t\t\t\tclient,\n\t\t\t\tonlyTransactionKind: false\n\t\t\t});\n\n\t\t\tconst dryRunResult = await client.dryRunTransactionBlock({\n\t\t\t\ttransactionBlock: builtTx\n\t\t\t});\n\n\t\t\tif (dryRunResult.effects.status?.status !== \"success\") {\n\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"dryRunFailed\", {\n\t\t\t\t\terror: dryRunResult.effects?.status?.error\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst result = {\n\t\t\t\tstatus: dryRunResult.effects.status.status,\n\t\t\t\tcosts: {\n\t\t\t\t\tcomputationCost: dryRunResult.effects.gasUsed.computationCost,\n\t\t\t\t\tcomputationCostBurned: dryRunResult.effects.gasUsed.computationCostBurned,\n\t\t\t\t\tstorageCost: dryRunResult.effects.gasUsed.storageCost,\n\t\t\t\t\tstorageRebate: dryRunResult.effects.gasUsed.storageRebate,\n\t\t\t\t\tnonRefundableStorageFee: dryRunResult.effects.gasUsed.nonRefundableStorageFee\n\t\t\t\t},\n\t\t\t\tevents: dryRunResult.events ?? [],\n\t\t\t\tbalanceChanges: dryRunResult.balanceChanges ?? [],\n\t\t\t\tobjectChanges: dryRunResult.objectChanges ?? []\n\t\t\t};\n\n\t\t\tawait logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: Iota.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"transactionCosts\",\n\t\t\t\tdata: {\n\t\t\t\t\toperation,\n\t\t\t\t\tcost: JSON.stringify(result)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (BaseError.isErrorName(error, GeneralError.CLASS_NAME)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"dryRunFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a transaction to be indexed and available over the API.\n\t * @param client The IOTA client instance.\n\t * @param digest The digest of the transaction to wait for.\n\t * @param config The IOTA configuration.\n\t * @param options Additional options for the transaction query.\n\t * @param options.showEffects Whether to show effects.\n\t * @param options.showEvents Whether to show events.\n\t * @param options.showObjectChanges Whether to show object changes.\n\t * @returns The confirmed transaction response.\n\t */\n\tpublic static async waitForTransactionConfirmation(\n\t\tclient: IotaClient,\n\t\tdigest: string,\n\t\tconfig: IIotaConfig,\n\t\toptions?: {\n\t\t\tshowEffects?: boolean;\n\t\t\tshowEvents?: boolean;\n\t\t\tshowObjectChanges?: boolean;\n\t\t}\n\t): Promise<IotaTransactionBlockResponse> {\n\t\tconst timeoutMs = (config.inclusionTimeoutSeconds ?? Iota.DEFAULT_INCLUSION_TIMEOUT) * 1000;\n\n\t\treturn client.waitForTransaction({\n\t\t\tdigest,\n\t\t\ttimeout: timeoutMs,\n\t\t\toptions: {\n\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Check if the error is an abort error.\n\t * @param error The error to check.\n\t * @param code The error code to check for.\n\t * @returns True if the error is an abort error, false otherwise.\n\t */\n\tpublic static isAbortError(error: unknown, code?: number): boolean {\n\t\tconst err = BaseError.fromError(error);\n\t\tif (Is.stringValue(err.properties?.error) && err.properties.error.startsWith(\"MoveAbort\")) {\n\t\t\tif (Is.number(code)) {\n\t\t\t\treturn err.properties.error.includes(code.toString());\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Prepare and post a transaction using gas station sponsoring.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param owner The owner of the address.\n\t * @param transaction The transaction to execute.\n\t * @param options Response options including confirmation behavior.\n\t * @returns The transaction response.\n\t */\n\tpublic static async prepareAndPostGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tidentity: string,\n\t\tclient: IotaClient,\n\t\towner: string,\n\t\ttransaction: Transaction,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IotaTransactionBlockResponse> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\ttry {\n\t\t\t// Reserve gas from the gas station\n\t\t\tconst gasBudget = config.gasBudget ?? 50000000;\n\t\t\tconst gasReservation = await Iota.reserveGas(config, gasBudget);\n\n\t\t\t// Set transaction parameters for sponsoring\n\t\t\ttransaction.setSender(owner);\n\t\t\ttransaction.setGasOwner(gasReservation.sponsorAddress);\n\t\t\ttransaction.setGasPayment(gasReservation.gasCoins);\n\t\t\ttransaction.setGasBudget(gasBudget);\n\n\t\t\t// Build and sign transaction\n\t\t\tconst unsignedTxBytes = await transaction.build({ client });\n\n\t\t\t// Sign the transaction with the user's private key\n\t\t\tconst seed = await Iota.getSeed(config, vaultConnector, identity);\n\t\t\tconst addressKeyPair = Iota.findAddress(\n\t\t\t\tconfig.maxAddressScanRange ?? Iota.DEFAULT_SCAN_RANGE,\n\t\t\t\tconfig.coinType ?? Iota.DEFAULT_COIN_TYPE,\n\t\t\t\tseed,\n\t\t\t\towner\n\t\t\t);\n\t\t\tconst keypair = Ed25519Keypair.fromSecretKey(addressKeyPair.privateKey);\n\t\t\tconst signature = await keypair.signTransaction(unsignedTxBytes);\n\n\t\t\treturn await Iota.executeAndConfirmGasStationTransaction(\n\t\t\t\tconfig,\n\t\t\t\tclient,\n\t\t\t\tgasReservation.reservationId,\n\t\t\t\tunsignedTxBytes,\n\t\t\t\tsignature.signature,\n\t\t\t\toptions\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"gasStationTransactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Reserve gas from the gas station.\n\t * @param config The configuration containing gas station settings.\n\t * @param gasBudget The gas budget to reserve.\n\t * @returns The gas reservation result.\n\t */\n\tpublic static async reserveGas(\n\t\tconfig: IIotaConfig,\n\t\tgasBudget: number\n\t): Promise<IGasReservationResult> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst requestData = {\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tgas_budget: gasBudget,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\treserve_duration_secs: 30\n\t\t};\n\n\t\tconst baseUrl = StringHelper.trimTrailingSlashes(config.gasStation.gasStationUrl);\n\t\tconst result = await FetchHelper.fetchJson<typeof requestData, IGasStationReserveGasResponse>(\n\t\t\tIota.CLASS_NAME,\n\t\t\t`${baseUrl}/v1/reserve_gas`,\n\t\t\tHttpMethod.POST,\n\t\t\trequestData,\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.gasStation.gasStationAuthToken}`\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\n\t\tconst apiResponse = result.result;\n\n\t\treturn {\n\t\t\tsponsorAddress: apiResponse.sponsor_address,\n\t\t\treservationId: apiResponse.reservation_id,\n\t\t\tgasCoins: apiResponse.gas_coins\n\t\t};\n\t}\n\n\t/**\n\t * Execute a sponsored transaction through the gas station.\n\t * @param config The configuration containing gas station settings.\n\t * @param reservationId The reservation ID from gas reservation.\n\t * @param transactionBytes The unsigned transaction bytes.\n\t * @param userSignature The user's signature.\n\t * @returns The transaction response.\n\t */\n\tpublic static async executeGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\treservationId: number,\n\t\ttransactionBytes: Uint8Array,\n\t\tuserSignature: string\n\t): Promise<IotaTransactionBlockResponse> {\n\t\tGuards.object<IGasStationConfig>(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst requestData = {\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\treservation_id: reservationId,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\ttx_bytes: Converter.bytesToBase64(transactionBytes),\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tuser_sig: userSignature\n\t\t};\n\n\t\tconst baseUrl = StringHelper.trimTrailingSlashes(config.gasStation.gasStationUrl);\n\t\tconst result = await FetchHelper.fetchJson<typeof requestData, IGasStationExecuteResponse>(\n\t\t\tIota.CLASS_NAME,\n\t\t\t`${baseUrl}/v1/execute_tx`,\n\t\t\tHttpMethod.POST,\n\t\t\trequestData,\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.gasStation.gasStationAuthToken}`\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\n\t\tconst effectsData = result.effects;\n\n\t\t// Match IotaTransactionBlockResponse format\n\t\treturn {\n\t\t\tdigest: effectsData.transactionDigest,\n\t\t\teffects: effectsData as unknown,\n\t\t\tevents: [],\n\t\t\tobjectChanges: [],\n\t\t\tconfirmedLocalExecution: true\n\t\t} as unknown as IotaTransactionBlockResponse;\n\t}\n\n\t/**\n\t * Execute and confirm a gas station transaction.\n\t * @param config The configuration containing gas station settings.\n\t * @param client The IOTA client for confirmation.\n\t * @param reservationId The reservation ID from gas reservation.\n\t * @param transactionBytes The unsigned transaction bytes.\n\t * @param userSignature The user's signature.\n\t * @param options Response options including confirmation behavior.\n\t * @returns The transaction response (confirmed if waitForConfirmation is true).\n\t */\n\tpublic static async executeAndConfirmGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\tclient: IotaClient,\n\t\treservationId: number,\n\t\ttransactionBytes: Uint8Array,\n\t\tuserSignature: string,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IotaTransactionBlockResponse> {\n\t\tGuards.object<IGasStationConfig>(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst response = await Iota.executeGasStationTransaction(\n\t\t\tconfig,\n\t\t\treservationId,\n\t\t\ttransactionBytes,\n\t\t\tuserSignature\n\t\t);\n\n\t\tif (options?.waitForConfirmation ?? true) {\n\t\t\tconst confirmedTransaction = await Iota.waitForTransactionConfirmation(\n\t\t\t\tclient,\n\t\t\t\tresponse.digest,\n\t\t\t\tconfig,\n\t\t\t\t{\n\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t}\n\t\t\t);\n\n\t\t\treturn confirmedTransaction;\n\t\t}\n\n\t\treturn response;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import { bcs } from "@iota/bcs";
|
|
4
|
+
import { Transaction } from "@iota/iota-sdk/transactions";
|
|
5
|
+
import { GeneralError, Is, StringHelper } from "@twin.org/core";
|
|
6
|
+
import { Iota } from "./iota.js";
|
|
7
|
+
/**
|
|
8
|
+
* Utility class providing common smart contract operations for IOTA-based contracts.
|
|
9
|
+
* This class uses composition pattern to provide shared functionality without inheritance complexity.
|
|
10
|
+
*/
|
|
11
|
+
export class IotaSmartContractUtils {
|
|
12
|
+
/**
|
|
13
|
+
* Runtime name for the class.
|
|
14
|
+
*/
|
|
15
|
+
static CLASS_NAME = "IotaSmartContractUtils";
|
|
16
|
+
/**
|
|
17
|
+
* Migrate a smart contract object to the current version using admin privileges.
|
|
18
|
+
* This is a generic migration method that works with any IOTA smart contract.
|
|
19
|
+
* @param config The IOTA configuration.
|
|
20
|
+
* @param client The IOTA client instance.
|
|
21
|
+
* @param vaultConnector The vault connector for key management.
|
|
22
|
+
* @param walletConnector The wallet connector for address generation.
|
|
23
|
+
* @param logging Optional logging component.
|
|
24
|
+
* @param gasBudget The gas budget for the transaction.
|
|
25
|
+
* @param identity The identity of the controller with admin privileges.
|
|
26
|
+
* @param objectId The ID of the object to migrate.
|
|
27
|
+
* @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
|
|
28
|
+
* @param packageId The deployed package ID for the contract.
|
|
29
|
+
* @param deploymentConfig The deployment configuration containing object IDs.
|
|
30
|
+
* @param walletAddressIndex Optional wallet address index for the controller.
|
|
31
|
+
* @returns Promise that resolves when migration is complete.
|
|
32
|
+
*/
|
|
33
|
+
static async migrateSmartContract(config, client, vaultConnector, walletConnector, logging, gasBudget, identity, objectId, namespace, packageId, deploymentConfig, walletAddressIndex) {
|
|
34
|
+
try {
|
|
35
|
+
const txb = new Transaction();
|
|
36
|
+
txb.setGasBudget(gasBudget);
|
|
37
|
+
const moduleName = IotaSmartContractUtils.getModuleName(namespace);
|
|
38
|
+
// Get admin address for the transaction
|
|
39
|
+
const adminAddress = await IotaSmartContractUtils.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
|
|
40
|
+
// Get the required object IDs from deployment config
|
|
41
|
+
const { adminCapId, migrationStateId } = await IotaSmartContractUtils.getContractObjectIds(client, namespace, config.network, deploymentConfig, packageId, adminAddress);
|
|
42
|
+
txb.moveCall({
|
|
43
|
+
target: `${packageId}::${moduleName}::migrate_${moduleName}`,
|
|
44
|
+
arguments: [txb.object(adminCapId), txb.object(migrationStateId), txb.object(objectId)]
|
|
45
|
+
});
|
|
46
|
+
const result = await Iota.prepareAndPostTransaction(config, vaultConnector, logging, identity, client, adminAddress, txb, {
|
|
47
|
+
dryRunLabel: config.enableCostLogging ? "migrate_object" : undefined
|
|
48
|
+
});
|
|
49
|
+
if (result.effects?.status?.status !== "success") {
|
|
50
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "migrationFailed", {
|
|
51
|
+
error: result.effects?.status?.error,
|
|
52
|
+
objectId
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "migrateSmartContractFailed", { objectId }, error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Enable migration operations using admin privileges.
|
|
62
|
+
* @param config The IOTA configuration.
|
|
63
|
+
* @param client The IOTA client instance.
|
|
64
|
+
* @param vaultConnector The vault connector for key management.
|
|
65
|
+
* @param walletConnector The wallet connector for address generation.
|
|
66
|
+
* @param logging Optional logging component.
|
|
67
|
+
* @param gasBudget The gas budget for the transaction.
|
|
68
|
+
* @param identity The identity of the controller with admin privileges.
|
|
69
|
+
* @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
|
|
70
|
+
* @param packageId The deployed package ID for the contract.
|
|
71
|
+
* @param deploymentConfig The deployment configuration containing object IDs.
|
|
72
|
+
* @param walletAddressIndex Optional wallet address index for the controller.
|
|
73
|
+
* @returns Promise that resolves when migration is enabled.
|
|
74
|
+
*/
|
|
75
|
+
static async enableMigration(config, client, vaultConnector, walletConnector, logging, gasBudget, identity, namespace, packageId, deploymentConfig, walletAddressIndex) {
|
|
76
|
+
try {
|
|
77
|
+
const txb = new Transaction();
|
|
78
|
+
txb.setGasBudget(gasBudget);
|
|
79
|
+
const moduleName = IotaSmartContractUtils.getModuleName(namespace);
|
|
80
|
+
// Get admin address for the transaction
|
|
81
|
+
const adminAddress = await IotaSmartContractUtils.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
|
|
82
|
+
// Get the required object IDs from deployment config
|
|
83
|
+
const { adminCapId, migrationStateId } = await IotaSmartContractUtils.getContractObjectIds(client, namespace, config.network, deploymentConfig, packageId, adminAddress);
|
|
84
|
+
txb.moveCall({
|
|
85
|
+
target: `${packageId}::${moduleName}::enable_migration`,
|
|
86
|
+
arguments: [txb.object(adminCapId), txb.object(migrationStateId)]
|
|
87
|
+
});
|
|
88
|
+
const result = await Iota.prepareAndPostTransaction(config, vaultConnector, logging, identity, client, adminAddress, txb, {
|
|
89
|
+
dryRunLabel: config.enableCostLogging ? "enable_migration" : undefined
|
|
90
|
+
});
|
|
91
|
+
if (result.effects?.status?.status !== "success") {
|
|
92
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "enableMigrationFailed", {
|
|
93
|
+
error: result.effects?.status?.error
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "enableMigrationFailed", undefined, error);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Disable migration operations using admin privileges.
|
|
103
|
+
* @param config The IOTA configuration.
|
|
104
|
+
* @param client The IOTA client instance.
|
|
105
|
+
* @param vaultConnector The vault connector for key management.
|
|
106
|
+
* @param walletConnector The wallet connector for address generation.
|
|
107
|
+
* @param logging Optional logging component.
|
|
108
|
+
* @param gasBudget The gas budget for the transaction.
|
|
109
|
+
* @param identity The identity of the controller with admin privileges.
|
|
110
|
+
* @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
|
|
111
|
+
* @param packageId The deployed package ID for the contract.
|
|
112
|
+
* @param deploymentConfig The deployment configuration containing object IDs.
|
|
113
|
+
* @param walletAddressIndex Optional wallet address index for the controller.
|
|
114
|
+
* @returns Promise that resolves when migration is disabled.
|
|
115
|
+
*/
|
|
116
|
+
static async disableMigration(config, client, vaultConnector, walletConnector, logging, gasBudget, identity, namespace, packageId, deploymentConfig, walletAddressIndex) {
|
|
117
|
+
try {
|
|
118
|
+
const txb = new Transaction();
|
|
119
|
+
txb.setGasBudget(gasBudget);
|
|
120
|
+
const moduleName = IotaSmartContractUtils.getModuleName(namespace);
|
|
121
|
+
// Get admin address for the transaction
|
|
122
|
+
const adminAddress = await IotaSmartContractUtils.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
|
|
123
|
+
// Get the required object IDs from deployment config
|
|
124
|
+
const { adminCapId, migrationStateId } = await IotaSmartContractUtils.getContractObjectIds(client, namespace, config.network, deploymentConfig, packageId, adminAddress);
|
|
125
|
+
txb.moveCall({
|
|
126
|
+
target: `${packageId}::${moduleName}::disable_migration`,
|
|
127
|
+
arguments: [txb.object(adminCapId), txb.object(migrationStateId)]
|
|
128
|
+
});
|
|
129
|
+
const result = await Iota.prepareAndPostTransaction(config, vaultConnector, logging, identity, client, adminAddress, txb, {
|
|
130
|
+
dryRunLabel: config.enableCostLogging ? "disable_migration" : undefined
|
|
131
|
+
});
|
|
132
|
+
if (result.effects?.status?.status !== "success") {
|
|
133
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "disableMigrationFailed", {
|
|
134
|
+
error: result.effects?.status?.error
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "disableMigrationFailed", undefined, error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if migration is currently active for a smart contract.
|
|
144
|
+
* @param config The IOTA configuration.
|
|
145
|
+
* @param client The IOTA client instance.
|
|
146
|
+
* @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
|
|
147
|
+
* @param packageId The deployed package ID for the contract.
|
|
148
|
+
* @param deploymentConfig The deployment configuration containing object IDs.
|
|
149
|
+
* @param identity The identity for MigrationState discovery.
|
|
150
|
+
* @param walletConnector The wallet connector for address generation.
|
|
151
|
+
* @param walletAddressIndex Optional wallet address index.
|
|
152
|
+
* @returns True if migration is enabled, false otherwise.
|
|
153
|
+
*/
|
|
154
|
+
static async isMigrationActive(config, client, namespace, packageId, deploymentConfig, identity, walletConnector, walletAddressIndex) {
|
|
155
|
+
try {
|
|
156
|
+
// Get admin address for discovery
|
|
157
|
+
const adminAddress = await IotaSmartContractUtils.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
|
|
158
|
+
// Get the migration state ID
|
|
159
|
+
const { migrationStateId } = await IotaSmartContractUtils.getContractObjectIds(client, namespace, config.network, deploymentConfig, packageId, adminAddress);
|
|
160
|
+
const migrationStateResponse = await client.getObject({
|
|
161
|
+
id: migrationStateId,
|
|
162
|
+
options: {
|
|
163
|
+
showContent: true,
|
|
164
|
+
showType: true
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
if (!migrationStateResponse.data?.content) {
|
|
168
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "migrationStateNotReadable", {
|
|
169
|
+
migrationStateId
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
const content = migrationStateResponse.data.content;
|
|
173
|
+
if (content.dataType === "moveObject" && Is.objectValue(content.fields)) {
|
|
174
|
+
const fields = content.fields;
|
|
175
|
+
return Is.boolean(fields.enabled) ? fields.enabled : false;
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "isMigrationActiveFailed", undefined, error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get the current contract version from the deployed smart contract.
|
|
185
|
+
* @param config The IOTA configuration.
|
|
186
|
+
* @param client The IOTA client instance.
|
|
187
|
+
* @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
|
|
188
|
+
* @param packageId The deployed package ID for the contract.
|
|
189
|
+
* @param identity The identity for package controller address.
|
|
190
|
+
* @param walletConnector The wallet connector for address generation.
|
|
191
|
+
* @param walletAddressIndex Optional wallet address index.
|
|
192
|
+
* @returns The current version number of the contract.
|
|
193
|
+
*/
|
|
194
|
+
static async getCurrentContractVersion(config, client, namespace, packageId, identity, walletConnector, walletAddressIndex) {
|
|
195
|
+
try {
|
|
196
|
+
const tx = new Transaction();
|
|
197
|
+
const moduleName = IotaSmartContractUtils.getModuleName(namespace);
|
|
198
|
+
tx.moveCall({
|
|
199
|
+
target: `${packageId}::${moduleName}::get_current_version`,
|
|
200
|
+
arguments: []
|
|
201
|
+
});
|
|
202
|
+
const controllerAddress = await IotaSmartContractUtils.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
|
|
203
|
+
const result = await client.devInspectTransactionBlock({
|
|
204
|
+
sender: controllerAddress,
|
|
205
|
+
transactionBlock: tx
|
|
206
|
+
});
|
|
207
|
+
if (Is.arrayValue(result.results) &&
|
|
208
|
+
Is.object(result.results[0]) &&
|
|
209
|
+
Is.arrayValue(result.results[0].returnValues)) {
|
|
210
|
+
const versionBytes = result.results[0].returnValues[0];
|
|
211
|
+
// Convert to Uint8Array if it's a regular array
|
|
212
|
+
const byteData = versionBytes[0];
|
|
213
|
+
if (!Is.arrayValue(byteData) && !Is.uint8Array(byteData)) {
|
|
214
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "invalidVersionData");
|
|
215
|
+
}
|
|
216
|
+
// Convert to Uint8Array for BCS parsing
|
|
217
|
+
const uint8Data = Is.uint8Array(byteData) ? byteData : new Uint8Array(byteData);
|
|
218
|
+
// The version is returned as a u64, decode it from bytes using BCS
|
|
219
|
+
// IOTA Move contracts return data in BCS format
|
|
220
|
+
const version = Number(bcs.u64().parse(uint8Data));
|
|
221
|
+
return version;
|
|
222
|
+
}
|
|
223
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "getCurrentContractVersionNoData", {
|
|
224
|
+
resultExists: Is.arrayValue(result.results),
|
|
225
|
+
resultLength: Is.arrayValue(result.results) ? result.results.length : 0,
|
|
226
|
+
hasReturnValues: Is.arrayValue(result.results?.[0]?.returnValues)
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "getCurrentContractVersionFailed", undefined, error);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Validate that an object version is compatible with the current contract.
|
|
235
|
+
* @param config The IOTA configuration.
|
|
236
|
+
* @param client The IOTA client instance.
|
|
237
|
+
* @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
|
|
238
|
+
* @param packageId The deployed package ID for the contract.
|
|
239
|
+
* @param identity The identity for version checking.
|
|
240
|
+
* @param objectId The object ID to validate.
|
|
241
|
+
* @param walletConnector The wallet connector for address generation.
|
|
242
|
+
* @param versionExtractor Function to extract version from object content.
|
|
243
|
+
* @param walletAddressIndex Optional wallet address index.
|
|
244
|
+
* @returns True if the object version is compatible, false otherwise.
|
|
245
|
+
*/
|
|
246
|
+
static async validateObjectVersion(config, client, namespace, packageId, identity, objectId, walletConnector, versionExtractor, walletAddressIndex) {
|
|
247
|
+
try {
|
|
248
|
+
// Get current contract version
|
|
249
|
+
const currentVersion = await IotaSmartContractUtils.getCurrentContractVersion(config, client, namespace, packageId, identity, walletConnector, walletAddressIndex);
|
|
250
|
+
// Get object version
|
|
251
|
+
const objectResponse = await client.getObject({
|
|
252
|
+
id: objectId,
|
|
253
|
+
options: {
|
|
254
|
+
showContent: true,
|
|
255
|
+
showType: true
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
if (!objectResponse.data?.content) {
|
|
259
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "objectNotReadable", {
|
|
260
|
+
objectId
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
const content = objectResponse.data.content;
|
|
264
|
+
if (content.dataType === "moveObject" && Is.objectValue(content.fields)) {
|
|
265
|
+
const objectVersion = versionExtractor(content);
|
|
266
|
+
return objectVersion <= currentVersion;
|
|
267
|
+
}
|
|
268
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "objectInvalidFormat", {
|
|
269
|
+
objectId,
|
|
270
|
+
content
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "validateObjectVersionFailed", { objectId }, error);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get the module name for a given namespace.
|
|
279
|
+
* @param namespace The contract namespace.
|
|
280
|
+
* @returns The module name in snake_case format.
|
|
281
|
+
* @internal
|
|
282
|
+
*/
|
|
283
|
+
static getModuleName(namespace) {
|
|
284
|
+
// Convert namespace to snake_case for module name
|
|
285
|
+
return StringHelper.snakeCase(namespace);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Get the package controller address for transactions.
|
|
289
|
+
* @param walletConnector The wallet connector for address generation.
|
|
290
|
+
* @param identity The identity to use.
|
|
291
|
+
* @param addressIndex Optional address index to use.
|
|
292
|
+
* @returns The controller address.
|
|
293
|
+
* @internal
|
|
294
|
+
*/
|
|
295
|
+
static async getPackageControllerAddress(walletConnector, identity, addressIndex = 0) {
|
|
296
|
+
const addresses = await walletConnector.getAddresses(identity, 0, addressIndex, 1);
|
|
297
|
+
return addresses[0];
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Get contract object IDs (AdminCap and MigrationState) from deployment config with fallback discovery.
|
|
301
|
+
* @param client The IOTA client instance.
|
|
302
|
+
* @param namespace The contract namespace.
|
|
303
|
+
* @param network The network name.
|
|
304
|
+
* @param deploymentConfig The deployment configuration.
|
|
305
|
+
* @param packageId The package ID.
|
|
306
|
+
* @param adminAddress The admin address for object discovery.
|
|
307
|
+
* @returns Object containing adminCapId and migrationStateId.
|
|
308
|
+
* @internal
|
|
309
|
+
*/
|
|
310
|
+
static async getContractObjectIds(client, namespace, network, deploymentConfig, packageId, adminAddress) {
|
|
311
|
+
try {
|
|
312
|
+
// First try to load from deployment JSON
|
|
313
|
+
const networkConfig = deploymentConfig[network];
|
|
314
|
+
if (Is.objectValue(networkConfig)) {
|
|
315
|
+
const migrationStateId = networkConfig.migrationStateId;
|
|
316
|
+
// AdminCap must be discovered from blockchain (not stored in JSON)
|
|
317
|
+
const adminCapId = await IotaSmartContractUtils.discoverAdminCap(client, packageId, namespace, adminAddress);
|
|
318
|
+
if (Is.stringValue(migrationStateId) && Is.stringValue(adminCapId)) {
|
|
319
|
+
return { adminCapId, migrationStateId };
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// Fallback: discover both from blockchain
|
|
323
|
+
return await IotaSmartContractUtils.discoverContractObjectsFromBlockchain(client, packageId, namespace, adminAddress);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "getContractObjectIdsFailed", { namespace, network, packageId }, error);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Discover AdminCap object from the blockchain.
|
|
331
|
+
* @param client The IOTA client instance.
|
|
332
|
+
* @param packageId The package ID.
|
|
333
|
+
* @param namespace The contract namespace.
|
|
334
|
+
* @param adminAddress The admin address.
|
|
335
|
+
* @returns The AdminCap object ID.
|
|
336
|
+
* @internal
|
|
337
|
+
*/
|
|
338
|
+
static async discoverAdminCap(client, packageId, namespace, adminAddress) {
|
|
339
|
+
const adminCapType = `${packageId}::${IotaSmartContractUtils.getModuleName(namespace)}::AdminCap`;
|
|
340
|
+
const adminCapObjects = await client.getOwnedObjects({
|
|
341
|
+
owner: adminAddress,
|
|
342
|
+
filter: {
|
|
343
|
+
StructType: adminCapType
|
|
344
|
+
},
|
|
345
|
+
options: {
|
|
346
|
+
showContent: true,
|
|
347
|
+
showType: true
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
if (Is.arrayValue(adminCapObjects.data) && adminCapObjects.data.length > 0) {
|
|
351
|
+
const adminCapObject = adminCapObjects.data[0];
|
|
352
|
+
if (Is.stringValue(adminCapObject.data?.objectId)) {
|
|
353
|
+
return adminCapObject.data.objectId;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "adminCapNotFound", {
|
|
357
|
+
adminCapType,
|
|
358
|
+
adminAddress
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Discover contract objects from blockchain as fallback.
|
|
363
|
+
* @param client The IOTA client instance.
|
|
364
|
+
* @param packageId The package ID.
|
|
365
|
+
* @param namespace The contract namespace.
|
|
366
|
+
* @param adminAddress The admin address.
|
|
367
|
+
* @returns Object containing adminCapId and migrationStateId.
|
|
368
|
+
* @internal
|
|
369
|
+
*/
|
|
370
|
+
static async discoverContractObjectsFromBlockchain(client, packageId, namespace, adminAddress) {
|
|
371
|
+
// Discover AdminCap
|
|
372
|
+
const adminCapId = await IotaSmartContractUtils.discoverAdminCap(client, packageId, namespace, adminAddress);
|
|
373
|
+
// Discover MigrationState through transaction history
|
|
374
|
+
const migrationStateType = `${packageId}::${IotaSmartContractUtils.getModuleName(namespace)}::MigrationState`;
|
|
375
|
+
const transactions = await client.queryTransactionBlocks({
|
|
376
|
+
filter: {
|
|
377
|
+
FromAddress: adminAddress
|
|
378
|
+
},
|
|
379
|
+
options: {
|
|
380
|
+
showObjectChanges: true,
|
|
381
|
+
showEffects: true
|
|
382
|
+
},
|
|
383
|
+
limit: 20,
|
|
384
|
+
order: "descending"
|
|
385
|
+
});
|
|
386
|
+
// Look for MigrationState object creation in transaction history
|
|
387
|
+
let migrationStateId;
|
|
388
|
+
for (const tx of transactions.data) {
|
|
389
|
+
const objectChanges = tx.objectChanges;
|
|
390
|
+
if (Is.arrayValue(objectChanges)) {
|
|
391
|
+
for (const change of objectChanges) {
|
|
392
|
+
if ((change.type === "created" || change.type === "mutated") &&
|
|
393
|
+
"objectType" in change &&
|
|
394
|
+
change.objectType === migrationStateType) {
|
|
395
|
+
migrationStateId = change.objectId;
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if (migrationStateId) {
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (!migrationStateId) {
|
|
405
|
+
throw new GeneralError(IotaSmartContractUtils.CLASS_NAME, "migrationStateNotFound", {
|
|
406
|
+
migrationStateType,
|
|
407
|
+
adminAddress
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
return { adminCapId, migrationStateId };
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=iotaSmartContractUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iotaSmartContractUtils.js","sourceRoot":"","sources":["../../src/iotaSmartContractUtils.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { bcs } from \"@iota/bcs\";\nimport type { IotaClient } from \"@iota/iota-sdk/client\";\nimport { Transaction } from \"@iota/iota-sdk/transactions\";\nimport { GeneralError, Is, StringHelper } from \"@twin.org/core\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { IVaultConnector } from \"@twin.org/vault-models\";\nimport type { IWalletConnector } from \"@twin.org/wallet-models\";\nimport { Iota } from \"./iota.js\";\nimport type { IIotaConfig } from \"./models/IIotaConfig.js\";\nimport type { ISmartContractDeployments } from \"./models/ISmartContractDeployments.js\";\nimport type { NetworkTypes } from \"./models/networkTypes.js\";\n\n/**\n * Utility class providing common smart contract operations for IOTA-based contracts.\n * This class uses composition pattern to provide shared functionality without inheritance complexity.\n */\nexport class IotaSmartContractUtils {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<IotaSmartContractUtils>();\n\n\t/**\n\t * Migrate a smart contract object to the current version using admin privileges.\n\t * This is a generic migration method that works with any IOTA smart contract.\n\t * @param config The IOTA configuration.\n\t * @param client The IOTA client instance.\n\t * @param vaultConnector The vault connector for key management.\n\t * @param walletConnector The wallet connector for address generation.\n\t * @param logging Optional logging component.\n\t * @param gasBudget The gas budget for the transaction.\n\t * @param identity The identity of the controller with admin privileges.\n\t * @param objectId The ID of the object to migrate.\n\t * @param namespace The contract namespace (e.g., \"nft\", \"verifiable_storage\").\n\t * @param packageId The deployed package ID for the contract.\n\t * @param deploymentConfig The deployment configuration containing object IDs.\n\t * @param walletAddressIndex Optional wallet address index for the controller.\n\t * @returns Promise that resolves when migration is complete.\n\t */\n\tpublic static async migrateSmartContract(\n\t\tconfig: IIotaConfig,\n\t\tclient: IotaClient,\n\t\tvaultConnector: IVaultConnector,\n\t\twalletConnector: IWalletConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tgasBudget: number,\n\t\tidentity: string,\n\t\tobjectId: string,\n\t\tnamespace: string,\n\t\tpackageId: string,\n\t\tdeploymentConfig: ISmartContractDeployments,\n\t\twalletAddressIndex?: number\n\t): Promise<void> {\n\t\ttry {\n\t\t\tconst txb = new Transaction();\n\t\t\ttxb.setGasBudget(gasBudget);\n\n\t\t\tconst moduleName = IotaSmartContractUtils.getModuleName(namespace);\n\n\t\t\t// Get admin address for the transaction\n\t\t\tconst adminAddress = await IotaSmartContractUtils.getPackageControllerAddress(\n\t\t\t\twalletConnector,\n\t\t\t\tidentity,\n\t\t\t\twalletAddressIndex\n\t\t\t);\n\n\t\t\t// Get the required object IDs from deployment config\n\t\t\tconst { adminCapId, migrationStateId } = await IotaSmartContractUtils.getContractObjectIds(\n\t\t\t\tclient,\n\t\t\t\tnamespace,\n\t\t\t\tconfig.network as NetworkTypes,\n\t\t\t\tdeploymentConfig,\n\t\t\t\tpackageId,\n\t\t\t\tadminAddress\n\t\t\t);\n\n\t\t\ttxb.moveCall({\n\t\t\t\ttarget: `${packageId}::${moduleName}::migrate_${moduleName}`,\n\t\t\t\targuments: [txb.object(adminCapId), txb.object(migrationStateId), txb.object(objectId)]\n\t\t\t});\n\n\t\t\tconst result = await Iota.prepareAndPostTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tlogging as ILoggingComponent,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\tadminAddress,\n\t\t\t\ttxb,\n\t\t\t\t{\n\t\t\t\t\tdryRunLabel: config.enableCostLogging ? \"migrate_object\" : undefined\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (result.effects?.status?.status !== \"success\") {\n\t\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"migrationFailed\", {\n\t\t\t\t\terror: result.effects?.status?.error,\n\t\t\t\t\tobjectId\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIotaSmartContractUtils.CLASS_NAME,\n\t\t\t\t\"migrateSmartContractFailed\",\n\t\t\t\t{ objectId },\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Enable migration operations using admin privileges.\n\t * @param config The IOTA configuration.\n\t * @param client The IOTA client instance.\n\t * @param vaultConnector The vault connector for key management.\n\t * @param walletConnector The wallet connector for address generation.\n\t * @param logging Optional logging component.\n\t * @param gasBudget The gas budget for the transaction.\n\t * @param identity The identity of the controller with admin privileges.\n\t * @param namespace The contract namespace (e.g., \"nft\", \"verifiable_storage\").\n\t * @param packageId The deployed package ID for the contract.\n\t * @param deploymentConfig The deployment configuration containing object IDs.\n\t * @param walletAddressIndex Optional wallet address index for the controller.\n\t * @returns Promise that resolves when migration is enabled.\n\t */\n\tpublic static async enableMigration(\n\t\tconfig: IIotaConfig,\n\t\tclient: IotaClient,\n\t\tvaultConnector: IVaultConnector,\n\t\twalletConnector: IWalletConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tgasBudget: number,\n\t\tidentity: string,\n\t\tnamespace: string,\n\t\tpackageId: string,\n\t\tdeploymentConfig: ISmartContractDeployments,\n\t\twalletAddressIndex?: number\n\t): Promise<void> {\n\t\ttry {\n\t\t\tconst txb = new Transaction();\n\t\t\ttxb.setGasBudget(gasBudget);\n\n\t\t\tconst moduleName = IotaSmartContractUtils.getModuleName(namespace);\n\n\t\t\t// Get admin address for the transaction\n\t\t\tconst adminAddress = await IotaSmartContractUtils.getPackageControllerAddress(\n\t\t\t\twalletConnector,\n\t\t\t\tidentity,\n\t\t\t\twalletAddressIndex\n\t\t\t);\n\n\t\t\t// Get the required object IDs from deployment config\n\t\t\tconst { adminCapId, migrationStateId } = await IotaSmartContractUtils.getContractObjectIds(\n\t\t\t\tclient,\n\t\t\t\tnamespace,\n\t\t\t\tconfig.network as NetworkTypes,\n\t\t\t\tdeploymentConfig,\n\t\t\t\tpackageId,\n\t\t\t\tadminAddress\n\t\t\t);\n\n\t\t\ttxb.moveCall({\n\t\t\t\ttarget: `${packageId}::${moduleName}::enable_migration`,\n\t\t\t\targuments: [txb.object(adminCapId), txb.object(migrationStateId)]\n\t\t\t});\n\n\t\t\tconst result = await Iota.prepareAndPostTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tlogging as ILoggingComponent,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\tadminAddress,\n\t\t\t\ttxb,\n\t\t\t\t{\n\t\t\t\t\tdryRunLabel: config.enableCostLogging ? \"enable_migration\" : undefined\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (result.effects?.status?.status !== \"success\") {\n\t\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"enableMigrationFailed\", {\n\t\t\t\t\terror: result.effects?.status?.error\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIotaSmartContractUtils.CLASS_NAME,\n\t\t\t\t\"enableMigrationFailed\",\n\t\t\t\tundefined,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Disable migration operations using admin privileges.\n\t * @param config The IOTA configuration.\n\t * @param client The IOTA client instance.\n\t * @param vaultConnector The vault connector for key management.\n\t * @param walletConnector The wallet connector for address generation.\n\t * @param logging Optional logging component.\n\t * @param gasBudget The gas budget for the transaction.\n\t * @param identity The identity of the controller with admin privileges.\n\t * @param namespace The contract namespace (e.g., \"nft\", \"verifiable_storage\").\n\t * @param packageId The deployed package ID for the contract.\n\t * @param deploymentConfig The deployment configuration containing object IDs.\n\t * @param walletAddressIndex Optional wallet address index for the controller.\n\t * @returns Promise that resolves when migration is disabled.\n\t */\n\tpublic static async disableMigration(\n\t\tconfig: IIotaConfig,\n\t\tclient: IotaClient,\n\t\tvaultConnector: IVaultConnector,\n\t\twalletConnector: IWalletConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tgasBudget: number,\n\t\tidentity: string,\n\t\tnamespace: string,\n\t\tpackageId: string,\n\t\tdeploymentConfig: ISmartContractDeployments,\n\t\twalletAddressIndex?: number\n\t): Promise<void> {\n\t\ttry {\n\t\t\tconst txb = new Transaction();\n\t\t\ttxb.setGasBudget(gasBudget);\n\n\t\t\tconst moduleName = IotaSmartContractUtils.getModuleName(namespace);\n\n\t\t\t// Get admin address for the transaction\n\t\t\tconst adminAddress = await IotaSmartContractUtils.getPackageControllerAddress(\n\t\t\t\twalletConnector,\n\t\t\t\tidentity,\n\t\t\t\twalletAddressIndex\n\t\t\t);\n\n\t\t\t// Get the required object IDs from deployment config\n\t\t\tconst { adminCapId, migrationStateId } = await IotaSmartContractUtils.getContractObjectIds(\n\t\t\t\tclient,\n\t\t\t\tnamespace,\n\t\t\t\tconfig.network as NetworkTypes,\n\t\t\t\tdeploymentConfig,\n\t\t\t\tpackageId,\n\t\t\t\tadminAddress\n\t\t\t);\n\n\t\t\ttxb.moveCall({\n\t\t\t\ttarget: `${packageId}::${moduleName}::disable_migration`,\n\t\t\t\targuments: [txb.object(adminCapId), txb.object(migrationStateId)]\n\t\t\t});\n\n\t\t\tconst result = await Iota.prepareAndPostTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tlogging as ILoggingComponent,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\tadminAddress,\n\t\t\t\ttxb,\n\t\t\t\t{\n\t\t\t\t\tdryRunLabel: config.enableCostLogging ? \"disable_migration\" : undefined\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (result.effects?.status?.status !== \"success\") {\n\t\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"disableMigrationFailed\", {\n\t\t\t\t\terror: result.effects?.status?.error\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIotaSmartContractUtils.CLASS_NAME,\n\t\t\t\t\"disableMigrationFailed\",\n\t\t\t\tundefined,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Check if migration is currently active for a smart contract.\n\t * @param config The IOTA configuration.\n\t * @param client The IOTA client instance.\n\t * @param namespace The contract namespace (e.g., \"nft\", \"verifiable_storage\").\n\t * @param packageId The deployed package ID for the contract.\n\t * @param deploymentConfig The deployment configuration containing object IDs.\n\t * @param identity The identity for MigrationState discovery.\n\t * @param walletConnector The wallet connector for address generation.\n\t * @param walletAddressIndex Optional wallet address index.\n\t * @returns True if migration is enabled, false otherwise.\n\t */\n\tpublic static async isMigrationActive(\n\t\tconfig: IIotaConfig,\n\t\tclient: IotaClient,\n\t\tnamespace: string,\n\t\tpackageId: string,\n\t\tdeploymentConfig: ISmartContractDeployments,\n\t\tidentity: string,\n\t\twalletConnector: IWalletConnector,\n\t\twalletAddressIndex?: number\n\t): Promise<boolean> {\n\t\ttry {\n\t\t\t// Get admin address for discovery\n\t\t\tconst adminAddress = await IotaSmartContractUtils.getPackageControllerAddress(\n\t\t\t\twalletConnector,\n\t\t\t\tidentity,\n\t\t\t\twalletAddressIndex\n\t\t\t);\n\n\t\t\t// Get the migration state ID\n\t\t\tconst { migrationStateId } = await IotaSmartContractUtils.getContractObjectIds(\n\t\t\t\tclient,\n\t\t\t\tnamespace,\n\t\t\t\tconfig.network as NetworkTypes,\n\t\t\t\tdeploymentConfig,\n\t\t\t\tpackageId,\n\t\t\t\tadminAddress\n\t\t\t);\n\n\t\t\tconst migrationStateResponse = await client.getObject({\n\t\t\t\tid: migrationStateId,\n\t\t\t\toptions: {\n\t\t\t\t\tshowContent: true,\n\t\t\t\t\tshowType: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!migrationStateResponse.data?.content) {\n\t\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"migrationStateNotReadable\", {\n\t\t\t\t\tmigrationStateId\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst content = migrationStateResponse.data.content;\n\t\t\tif (content.dataType === \"moveObject\" && Is.objectValue(content.fields)) {\n\t\t\t\tconst fields = content.fields as { enabled: boolean };\n\t\t\t\treturn Is.boolean(fields.enabled) ? fields.enabled : false;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIotaSmartContractUtils.CLASS_NAME,\n\t\t\t\t\"isMigrationActiveFailed\",\n\t\t\t\tundefined,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get the current contract version from the deployed smart contract.\n\t * @param config The IOTA configuration.\n\t * @param client The IOTA client instance.\n\t * @param namespace The contract namespace (e.g., \"nft\", \"verifiable_storage\").\n\t * @param packageId The deployed package ID for the contract.\n\t * @param identity The identity for package controller address.\n\t * @param walletConnector The wallet connector for address generation.\n\t * @param walletAddressIndex Optional wallet address index.\n\t * @returns The current version number of the contract.\n\t */\n\tpublic static async getCurrentContractVersion(\n\t\tconfig: IIotaConfig,\n\t\tclient: IotaClient,\n\t\tnamespace: string,\n\t\tpackageId: string,\n\t\tidentity: string,\n\t\twalletConnector: IWalletConnector,\n\t\twalletAddressIndex?: number\n\t): Promise<number> {\n\t\ttry {\n\t\t\tconst tx = new Transaction();\n\t\t\tconst moduleName = IotaSmartContractUtils.getModuleName(namespace);\n\n\t\t\ttx.moveCall({\n\t\t\t\ttarget: `${packageId}::${moduleName}::get_current_version`,\n\t\t\t\targuments: []\n\t\t\t});\n\n\t\t\tconst controllerAddress = await IotaSmartContractUtils.getPackageControllerAddress(\n\t\t\t\twalletConnector,\n\t\t\t\tidentity,\n\t\t\t\twalletAddressIndex\n\t\t\t);\n\n\t\t\tconst result = await client.devInspectTransactionBlock({\n\t\t\t\tsender: controllerAddress,\n\t\t\t\ttransactionBlock: tx\n\t\t\t});\n\n\t\t\tif (\n\t\t\t\tIs.arrayValue(result.results) &&\n\t\t\t\tIs.object(result.results[0]) &&\n\t\t\t\tIs.arrayValue<Uint8Array>(result.results[0].returnValues)\n\t\t\t) {\n\t\t\t\tconst versionBytes = result.results[0].returnValues[0];\n\n\t\t\t\t// Convert to Uint8Array if it's a regular array\n\t\t\t\tconst byteData = versionBytes[0];\n\t\t\t\tif (!Is.arrayValue(byteData) && !Is.uint8Array(byteData)) {\n\t\t\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"invalidVersionData\");\n\t\t\t\t}\n\n\t\t\t\t// Convert to Uint8Array for BCS parsing\n\t\t\t\tconst uint8Data = Is.uint8Array(byteData) ? byteData : new Uint8Array(byteData);\n\n\t\t\t\t// The version is returned as a u64, decode it from bytes using BCS\n\t\t\t\t// IOTA Move contracts return data in BCS format\n\t\t\t\tconst version = Number(bcs.u64().parse(uint8Data));\n\t\t\t\treturn version;\n\t\t\t}\n\n\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"getCurrentContractVersionNoData\", {\n\t\t\t\tresultExists: Is.arrayValue(result.results),\n\t\t\t\tresultLength: Is.arrayValue(result.results) ? result.results.length : 0,\n\t\t\t\thasReturnValues: Is.arrayValue(result.results?.[0]?.returnValues)\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIotaSmartContractUtils.CLASS_NAME,\n\t\t\t\t\"getCurrentContractVersionFailed\",\n\t\t\t\tundefined,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Validate that an object version is compatible with the current contract.\n\t * @param config The IOTA configuration.\n\t * @param client The IOTA client instance.\n\t * @param namespace The contract namespace (e.g., \"nft\", \"verifiable_storage\").\n\t * @param packageId The deployed package ID for the contract.\n\t * @param identity The identity for version checking.\n\t * @param objectId The object ID to validate.\n\t * @param walletConnector The wallet connector for address generation.\n\t * @param versionExtractor Function to extract version from object content.\n\t * @param walletAddressIndex Optional wallet address index.\n\t * @returns True if the object version is compatible, false otherwise.\n\t */\n\tpublic static async validateObjectVersion<T>(\n\t\tconfig: IIotaConfig,\n\t\tclient: IotaClient,\n\t\tnamespace: string,\n\t\tpackageId: string,\n\t\tidentity: string,\n\t\tobjectId: string,\n\t\twalletConnector: IWalletConnector,\n\t\tversionExtractor: (content: T) => number,\n\t\twalletAddressIndex?: number\n\t): Promise<boolean> {\n\t\ttry {\n\t\t\t// Get current contract version\n\t\t\tconst currentVersion = await IotaSmartContractUtils.getCurrentContractVersion(\n\t\t\t\tconfig,\n\t\t\t\tclient,\n\t\t\t\tnamespace,\n\t\t\t\tpackageId,\n\t\t\t\tidentity,\n\t\t\t\twalletConnector,\n\t\t\t\twalletAddressIndex\n\t\t\t);\n\n\t\t\t// Get object version\n\t\t\tconst objectResponse = await client.getObject({\n\t\t\t\tid: objectId,\n\t\t\t\toptions: {\n\t\t\t\t\tshowContent: true,\n\t\t\t\t\tshowType: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!objectResponse.data?.content) {\n\t\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"objectNotReadable\", {\n\t\t\t\t\tobjectId\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst content = objectResponse.data.content;\n\t\t\tif (content.dataType === \"moveObject\" && Is.objectValue(content.fields)) {\n\t\t\t\tconst objectVersion = versionExtractor(content as T);\n\t\t\t\treturn objectVersion <= currentVersion;\n\t\t\t}\n\n\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"objectInvalidFormat\", {\n\t\t\t\tobjectId,\n\t\t\t\tcontent\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIotaSmartContractUtils.CLASS_NAME,\n\t\t\t\t\"validateObjectVersionFailed\",\n\t\t\t\t{ objectId },\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get the module name for a given namespace.\n\t * @param namespace The contract namespace.\n\t * @returns The module name in snake_case format.\n\t * @internal\n\t */\n\tprivate static getModuleName(namespace: string): string {\n\t\t// Convert namespace to snake_case for module name\n\t\treturn StringHelper.snakeCase(namespace);\n\t}\n\n\t/**\n\t * Get the package controller address for transactions.\n\t * @param walletConnector The wallet connector for address generation.\n\t * @param identity The identity to use.\n\t * @param addressIndex Optional address index to use.\n\t * @returns The controller address.\n\t * @internal\n\t */\n\tprivate static async getPackageControllerAddress(\n\t\twalletConnector: IWalletConnector,\n\t\tidentity: string,\n\t\taddressIndex = 0\n\t): Promise<string> {\n\t\tconst addresses = await walletConnector.getAddresses(identity, 0, addressIndex, 1);\n\t\treturn addresses[0];\n\t}\n\n\t/**\n\t * Get contract object IDs (AdminCap and MigrationState) from deployment config with fallback discovery.\n\t * @param client The IOTA client instance.\n\t * @param namespace The contract namespace.\n\t * @param network The network name.\n\t * @param deploymentConfig The deployment configuration.\n\t * @param packageId The package ID.\n\t * @param adminAddress The admin address for object discovery.\n\t * @returns Object containing adminCapId and migrationStateId.\n\t * @internal\n\t */\n\tprivate static async getContractObjectIds(\n\t\tclient: IotaClient,\n\t\tnamespace: string,\n\t\tnetwork: NetworkTypes,\n\t\tdeploymentConfig: ISmartContractDeployments,\n\t\tpackageId: string,\n\t\tadminAddress: string\n\t): Promise<{ adminCapId: string; migrationStateId: string }> {\n\t\ttry {\n\t\t\t// First try to load from deployment JSON\n\t\t\tconst networkConfig = deploymentConfig[network];\n\t\t\tif (Is.objectValue(networkConfig)) {\n\t\t\t\tconst migrationStateId = networkConfig.migrationStateId;\n\n\t\t\t\t// AdminCap must be discovered from blockchain (not stored in JSON)\n\t\t\t\tconst adminCapId = await IotaSmartContractUtils.discoverAdminCap(\n\t\t\t\t\tclient,\n\t\t\t\t\tpackageId,\n\t\t\t\t\tnamespace,\n\t\t\t\t\tadminAddress\n\t\t\t\t);\n\n\t\t\t\tif (Is.stringValue(migrationStateId) && Is.stringValue(adminCapId)) {\n\t\t\t\t\treturn { adminCapId, migrationStateId };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fallback: discover both from blockchain\n\t\t\treturn await IotaSmartContractUtils.discoverContractObjectsFromBlockchain(\n\t\t\t\tclient,\n\t\t\t\tpackageId,\n\t\t\t\tnamespace,\n\t\t\t\tadminAddress\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIotaSmartContractUtils.CLASS_NAME,\n\t\t\t\t\"getContractObjectIdsFailed\",\n\t\t\t\t{ namespace, network, packageId },\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Discover AdminCap object from the blockchain.\n\t * @param client The IOTA client instance.\n\t * @param packageId The package ID.\n\t * @param namespace The contract namespace.\n\t * @param adminAddress The admin address.\n\t * @returns The AdminCap object ID.\n\t * @internal\n\t */\n\tprivate static async discoverAdminCap(\n\t\tclient: IotaClient,\n\t\tpackageId: string,\n\t\tnamespace: string,\n\t\tadminAddress: string\n\t): Promise<string> {\n\t\tconst adminCapType = `${packageId}::${IotaSmartContractUtils.getModuleName(namespace)}::AdminCap`;\n\n\t\tconst adminCapObjects = await client.getOwnedObjects({\n\t\t\towner: adminAddress,\n\t\t\tfilter: {\n\t\t\t\tStructType: adminCapType\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowContent: true,\n\t\t\t\tshowType: true\n\t\t\t}\n\t\t});\n\n\t\tif (Is.arrayValue(adminCapObjects.data) && adminCapObjects.data.length > 0) {\n\t\t\tconst adminCapObject = adminCapObjects.data[0];\n\t\t\tif (Is.stringValue(adminCapObject.data?.objectId)) {\n\t\t\t\treturn adminCapObject.data.objectId;\n\t\t\t}\n\t\t}\n\n\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"adminCapNotFound\", {\n\t\t\tadminCapType,\n\t\t\tadminAddress\n\t\t});\n\t}\n\n\t/**\n\t * Discover contract objects from blockchain as fallback.\n\t * @param client The IOTA client instance.\n\t * @param packageId The package ID.\n\t * @param namespace The contract namespace.\n\t * @param adminAddress The admin address.\n\t * @returns Object containing adminCapId and migrationStateId.\n\t * @internal\n\t */\n\tprivate static async discoverContractObjectsFromBlockchain(\n\t\tclient: IotaClient,\n\t\tpackageId: string,\n\t\tnamespace: string,\n\t\tadminAddress: string\n\t): Promise<{ adminCapId: string; migrationStateId: string }> {\n\t\t// Discover AdminCap\n\t\tconst adminCapId = await IotaSmartContractUtils.discoverAdminCap(\n\t\t\tclient,\n\t\t\tpackageId,\n\t\t\tnamespace,\n\t\t\tadminAddress\n\t\t);\n\n\t\t// Discover MigrationState through transaction history\n\t\tconst migrationStateType = `${packageId}::${IotaSmartContractUtils.getModuleName(namespace)}::MigrationState`;\n\n\t\tconst transactions = await client.queryTransactionBlocks({\n\t\t\tfilter: {\n\t\t\t\tFromAddress: adminAddress\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowObjectChanges: true,\n\t\t\t\tshowEffects: true\n\t\t\t},\n\t\t\tlimit: 20,\n\t\t\torder: \"descending\"\n\t\t});\n\n\t\t// Look for MigrationState object creation in transaction history\n\t\tlet migrationStateId: string | undefined;\n\t\tfor (const tx of transactions.data) {\n\t\t\tconst objectChanges = tx.objectChanges;\n\t\t\tif (Is.arrayValue(objectChanges)) {\n\t\t\t\tfor (const change of objectChanges) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t(change.type === \"created\" || change.type === \"mutated\") &&\n\t\t\t\t\t\t\"objectType\" in change &&\n\t\t\t\t\t\tchange.objectType === migrationStateType\n\t\t\t\t\t) {\n\t\t\t\t\t\tmigrationStateId = change.objectId;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (migrationStateId) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!migrationStateId) {\n\t\t\tthrow new GeneralError(IotaSmartContractUtils.CLASS_NAME, \"migrationStateNotFound\", {\n\t\t\t\tmigrationStateType,\n\t\t\t\tadminAddress\n\t\t\t});\n\t\t}\n\n\t\treturn { adminCapId, migrationStateId };\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IAdminCapFields.js","sourceRoot":"","sources":["../../../src/models/IAdminCapFields.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Generic interface representing the storage fields of an AdminCap object.\n */\nexport interface IAdminCapFields {\n\t/**\n\t * The ID of the AdminCap object.\n\t */\n\tid: {\n\t\t/**\n\t\t * The ID of the AdminCap object.\n\t\t */\n\t\tid: string; // UID is an object with an 'id' field\n\t};\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IContractData.js","sourceRoot":"","sources":["../../../src/models/IContractData.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Interface for contract data stored in smart-contract-deployments.json\n */\nexport interface IContractData {\n\t/**\n\t * Package ID generated during build\n\t */\n\tpackageId: string;\n\n\t/**\n\t * Base64-encoded package bytecode\n\t */\n\tpackageBytecode: string | string[];\n\n\t/**\n\t * Package ID from actual deployment\n\t */\n\tdeployedPackageId?: string;\n\n\t/**\n\t * Previous deployed package ID for upgrade chain tracking\n\t */\n\tlastDeployedPackageId?: string;\n\n\t/**\n\t * UpgradeCap object ID for package upgrades\n\t */\n\tupgradeCapabilityId?: string;\n\n\t/**\n\t * Migration state ID for tracking contract migrations\n\t */\n\tmigrationStateId?: string;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IGasReservationResult.js","sourceRoot":"","sources":["../../../src/models/IGasReservationResult.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ObjectRef } from \"@iota/iota-sdk/transactions\";\n\n/**\n * Interface for gas reservation result from the gas station (with TypeScript camelCase conventions).\n */\nexport interface IGasReservationResult {\n\t/**\n\t * The sponsor's on-chain address.\n\t */\n\tsponsorAddress: string;\n\n\t/**\n\t * An ID used to reference this particular gas reservation.\n\t */\n\treservationId: number;\n\n\t/**\n\t * References to the sponsor's coins that will pay gas.\n\t */\n\tgasCoins: ObjectRef[];\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IGasStationConfig.js","sourceRoot":"","sources":["../../../src/models/IGasStationConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Configuration for gas station operations.\n */\nexport interface IGasStationConfig {\n\t/**\n\t * The gas station service URL.\n\t */\n\tgasStationUrl: string;\n\n\t/**\n\t * The authentication token for the gas station API.\n\t */\n\tgasStationAuthToken: string;\n}\n"]}
|