diff --git a/packages/cactus-common/src/main/typescript/error-utils.ts b/packages/cactus-common/src/main/typescript/error-utils.ts index d8f2898a000..43e5ebf60a6 100644 --- a/packages/cactus-common/src/main/typescript/error-utils.ts +++ b/packages/cactus-common/src/main/typescript/error-utils.ts @@ -28,5 +28,16 @@ export function safeStringifyException(error: unknown): string { return sanitizeHtml(error.stack || error.message); } + // Axios and possibly other lib errors produce nicer output with toJSON() method. + // Use it if available + if ( + error && + typeof error === "object" && + "toJSON" in error && + typeof error.toJSON === "function" + ) { + return sanitizeHtml(error.toJSON()); + } + return sanitizeHtml(safeStringify(error)); } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/README.md b/packages/cactus-plugin-ledger-connector-ethereum/README.md index 52533de45dd..ed08b27370c 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/README.md +++ b/packages/cactus-plugin-ledger-connector-ethereum/README.md @@ -52,7 +52,7 @@ async transact(req: RunTransactionRequest): Promise; async transactSigned(rawTransaction: string): Promise; async transactGethKeychain(txIn: RunTransactionRequest): Promise; async transactPrivateKey(req: RunTransactionRequest): Promise; -async transactCactusKeychainRef(req: RunTransactionRequest):Promise; +async transactCactiKeychainRef(req: RunTransactionRequest):Promise; async deployContract(req: DeployContractSolidityBytecodeV1Request :Promise; async deployContractJsonObject(req: DeployContractSolidityBytecodeJsonObjectV1Request): Promise async invokeRawWeb3EthMethod(req: InvokeRawWeb3EthMethodV1Request): Promise; @@ -77,7 +77,7 @@ The field "type" can have the following values: ```typescript enum Web3SigningCredentialType { - CACTUSKEYCHAINREF = "CACTUS_KEYCHAIN_REF", + CACTUSKEYCHAINREF = "CACTI_KEYCHAIN_REF", GETHKEYCHAINPASSWORD = "GETH_KEYCHAIN_PASSWORD", PRIVATEKEYHEX = "PRIVATE_KEY_HEX", NONE = "NONE", diff --git a/packages/cactus-plugin-ledger-connector-ethereum/package.json b/packages/cactus-plugin-ledger-connector-ethereum/package.json index f053715ded1..c3cb33242ce 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/package.json +++ b/packages/cactus-plugin-ledger-connector-ethereum/package.json @@ -4,6 +4,7 @@ "description": "Allows Cactus nodes to connect to a Ethereum ledger.", "keywords": [ "Hyperledger", + "Cacti", "Cactus", "Integration", "Blockchain", @@ -19,9 +20,9 @@ }, "license": "Apache-2.0", "author": { - "name": "Hyperledger Cactus Contributors", - "email": "cactus@lists.hyperledger.org", - "url": "https://www.hyperledger.org/use/cactus" + "name": "Hyperledger Cacti Contributors", + "email": "cacti@lists.hyperledger.org", + "url": "https://www.hyperledger.org/use/cacti" }, "contributors": [ { diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/json/openapi.json b/packages/cactus-plugin-ledger-connector-ethereum/src/main/json/openapi.json index 70fa929f2b0..aeb4b330527 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/json/openapi.json +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/json/openapi.json @@ -1,7 +1,7 @@ { "openapi": "3.0.3", "info": { - "title": "Hyperledger Cactus Plugin - Connector Ethereum", + "title": "Hyperledger Cacti Plugin - Connector Ethereum", "description": "Can perform basic tasks on a Ethereum ledger", "version": "v2.0.0-alpha.2", "license": { @@ -22,7 +22,7 @@ "$ref": "#/components/schemas/Web3SigningCredentialGethKeychainPassword" }, { - "$ref": "#/components/schemas/Web3SigningCredentialCactusKeychainRef" + "$ref": "#/components/schemas/Web3SigningCredentialCactiKeychainRef" }, { "$ref": "#/components/schemas/Web3SigningCredentialPrivateKeyHex" @@ -59,7 +59,7 @@ } } }, - "Web3SigningCredentialCactusKeychainRef": { + "Web3SigningCredentialCactiKeychainRef": { "type": "object", "required": ["type", "ethAccount", "keychainEntryKey"], "properties": { @@ -122,7 +122,7 @@ "Web3SigningCredentialType": { "type": "string", "enum": [ - "CACTUS_KEYCHAIN_REF", + "CACTI_KEYCHAIN_REF", "GETH_KEYCHAIN_PASSWORD", "PRIVATE_KEY_HEX", "NONE" @@ -136,77 +136,6 @@ "type": "string", "enum": ["send", "call", "encodeABI", "estimateGas"] }, - "SolidityContractJsonArtifact": { - "type": "object", - "required": ["contractName"], - "properties": { - "contractName": { - "type": "string", - "nullable": false - }, - "metadata": { - "type": "string", - "nullable": false - }, - "bytecode": { - "type": "string", - "nullable": false - }, - "deployedBytecode": { - "type": "string", - "nullable": false - }, - "sourceMap": { - "type": "string", - "nullable": false - }, - "deployedSourceMap": { - "type": "string", - "nullable": false - }, - "sourcePath": { - "type": "string" - }, - "compiler": { - "type": "object", - "additionalProperties": true, - "properties": { - "name": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, - "functionHashes": { - "type": "object", - "additionalProperties": true - }, - "gasEstimates": { - "properties": { - "creation": { - "type": "object", - "properties": { - "codeDepositCost": { - "type": "string" - }, - "executionCost": { - "type": "string" - }, - "totalCost": { - "type": "string" - } - } - }, - "external": { - "type": "object", - "additionalProperties": true - } - } - } - } - }, "GasTransactionConfigLegacy": { "type": "object", "description": "Transaction gas settings in networks before EIP-1559 (London fork).", @@ -378,7 +307,7 @@ }, "ContractJSON": { "type": "object", - "required": ["contractName", "bytecode"], + "required": ["contractName", "bytecode", "abi"], "additionalProperties": true, "properties": { "contractName": { @@ -430,40 +359,35 @@ } } }, - "RunTransactionRequest": { + "ContractJsonDefinition": { "type": "object", - "required": ["web3SigningCredential", "transactionConfig"], + "required": ["contractJSON"], "additionalProperties": false, "properties": { - "web3SigningCredential": { - "$ref": "#/components/schemas/Web3SigningCredential", - "nullable": false - }, - "transactionConfig": { - "$ref": "#/components/schemas/EthereumTransactionConfig", - "nullable": false - }, - "timeoutMs": { - "type": "number", - "description": "The amount of milliseconds to wait for a transaction receipt with thehash of the transaction(which indicates successful execution) beforegiving up and crashing.", - "minimum": 0, - "default": 60000, + "contractJSON": { + "$ref": "#/components/schemas/ContractJSON", "nullable": false } } }, - "RunTransactionResponse": { + "DeployedContractJsonDefinition": { "type": "object", - "required": ["transactionReceipt"], + "required": ["contractJSON", "contractAddress"], + "additionalProperties": false, "properties": { - "transactionReceipt": { - "$ref": "#/components/schemas/Web3TransactionReceipt" + "contractJSON": { + "$ref": "#/components/schemas/ContractJSON", + "nullable": false + }, + "contractAddress": { + "type": "string", + "nullable": false } } }, - "DeployContractSolidityBytecodeV1Request": { + "ContractKeychainDefinition": { "type": "object", - "required": ["contractName", "web3SigningCredential", "keychainId"], + "required": ["contractName", "keychainId"], "additionalProperties": false, "properties": { "contractName": { @@ -473,63 +397,38 @@ "maxLength": 100, "nullable": false }, - "contractAbi": { - "description": "The application binary interface of the solidity contract", - "type": "array", - "items": {}, - "nullable": false - }, - "web3SigningCredential": { - "$ref": "#/components/schemas/Web3SigningCredential", - "nullable": false - }, - "bytecode": { - "type": "string", - "nullable": false, - "minLength": 1, - "maxLength": 24576, - "description": "See https://ethereum.stackexchange.com/a/47556 regarding the maximum length of the bytecode" - }, "keychainId": { "type": "string", "description": "The keychainId for retrieve the contracts json.", "minLength": 1, "maxLength": 100, "nullable": false - }, - "gasConfig": { - "$ref": "#/components/schemas/GasTransactionConfig", - "nullable": false - }, - "nonce": { - "type": "number", + } + } + }, + "RunTransactionRequest": { + "type": "object", + "required": ["web3SigningCredential", "transactionConfig"], + "additionalProperties": false, + "properties": { + "web3SigningCredential": { + "$ref": "#/components/schemas/Web3SigningCredential", "nullable": false }, - "value": { - "type": "number", + "transactionConfig": { + "$ref": "#/components/schemas/EthereumTransactionConfig", "nullable": false }, "timeoutMs": { "type": "number", - "description": "The amount of milliseconds to wait for a transaction receipt with theaddress of the contract(which indicates successful deployment) beforegiving up and crashing.", + "description": "The amount of milliseconds to wait for a transaction receipt with thehash of the transaction(which indicates successful execution) beforegiving up and crashing.", "minimum": 0, "default": 60000, "nullable": false - }, - "contractJSON": { - "type": "object", - "description": "For use when not using keychain, pass the contract in as this variable", - "nullable": false - }, - "constructorArgs": { - "description": "The list of arguments to pass in to the constructor of the contract being deployed.", - "type": "array", - "default": [], - "items": {} } } }, - "DeployContractSolidityBytecodeV1Response": { + "RunTransactionResponse": { "type": "object", "required": ["transactionReceipt"], "properties": { @@ -538,29 +437,26 @@ } } }, - "DeployContractSolidityBytecodeJsonObjectV1Request": { + "DeployContractV1Request": { "type": "object", - "required": ["web3SigningCredential", "contractJSON"], + "required": ["web3SigningCredential", "contract"], "additionalProperties": false, "properties": { "web3SigningCredential": { "$ref": "#/components/schemas/Web3SigningCredential", "nullable": false }, - "gasConfig": { - "$ref": "#/components/schemas/GasTransactionConfig", - "nullable": false - }, - "timeoutMs": { - "type": "number", - "description": "The amount of milliseconds to wait for a transaction receipt with theaddress of the contract(which indicates successful deployment) beforegiving up and crashing.", - "minimum": 0, - "default": 60000, - "nullable": false - }, - "contractJSON": { - "$ref": "#/components/schemas/ContractJSON", - "description": "For use when not using keychain, pass the contract in as this variable", + "contract": { + "oneOf": [ + { + "$ref": "#/components/schemas/ContractJsonDefinition", + "description": "Send contract ABI directly in the request." + }, + { + "$ref": "#/components/schemas/ContractKeychainDefinition", + "description": "Read contract definition from the keychain plugin." + } + ], "nullable": false }, "constructorArgs": { @@ -568,94 +464,36 @@ "type": "array", "default": [], "items": {} - } - } - }, - "InvokeContractV1Request": { - "type": "object", - "required": [ - "web3SigningCredential", - "invocationType", - "methodName", - "params", - "contractName", - "keychainId" - ], - "additionalProperties": false, - "properties": { - "contractName": { - "description": "The contract name to find it in the keychain plugin", - "type": "string", - "nullable": false - }, - "web3SigningCredential": { - "$ref": "#/components/schemas/Web3SigningCredential", - "nullable": false - }, - "invocationType": { - "$ref": "#/components/schemas/EthContractInvocationType", - "nullable": false, - "description": "Indicates wether it is a CALL or a SEND type of invocation where only SEND ends up creating an actual transaction on the ledger." - }, - "methodName": { - "description": "The name of the contract method to invoke.", - "type": "string", - "nullable": false, - "minLength": 1, - "maxLength": 2048 - }, - "params": { - "description": "The list of arguments to pass in to the contract method being invoked.", - "type": "array", - "default": [], - "items": {} - }, - "value": { - "type": "string" }, "gasConfig": { "$ref": "#/components/schemas/GasTransactionConfig", "nullable": false }, - "nonce": { - "type": "string" - }, - "timeoutMs": { - "type": "number", - "description": "The amount of milliseconds to wait for a transaction receipt beforegiving up and crashing. Only has any effect if the invocation type is SEND", - "minimum": 0, - "default": 60000, - "nullable": false - }, - "keychainId": { + "value": { "type": "string", - "description": "The keychainId for retrieve the contracts json.", - "minLength": 1, - "maxLength": 100 + "description": "Ether balance to send on deployment.", + "nullable": false } } }, - "InvokeContractJsonObjectV1Request": { + "InvokeContractV1Request": { "type": "object", - "required": [ - "web3SigningCredential", - "invocationType", - "methodName", - "params", - "contractJSON", - "contractAddress" - ], + "required": ["contract", "methodName", "params", "invocationType"], "additionalProperties": false, "properties": { - "web3SigningCredential": { - "$ref": "#/components/schemas/Web3SigningCredential", + "contract": { + "oneOf": [ + { + "$ref": "#/components/schemas/DeployedContractJsonDefinition", + "description": "Send contract ABI and address directly in the request." + }, + { + "$ref": "#/components/schemas/ContractKeychainDefinition", + "description": "Read contract definition from the keychain plugin." + } + ], "nullable": false }, - "invocationType": { - "$ref": "#/components/schemas/EthContractInvocationType", - "nullable": false, - "description": "Indicates wether it is a CALL or a SEND type of invocation where only SEND ends up creating an actual transaction on the ledger." - }, "methodName": { "description": "The name of the contract method to invoke.", "type": "string", @@ -669,32 +507,28 @@ "default": [], "items": {} }, - "contractAddress": { - "description": "Address of the solidity contract", - "type": "string", - "nullable": false + "invocationType": { + "$ref": "#/components/schemas/EthContractInvocationType", + "nullable": false, + "description": "Indicates wether it is a CALL or a SEND type of invocation where only SEND ends up creating an actual transaction on the ledger." }, - "value": { - "type": "string" + "web3SigningCredential": { + "$ref": "#/components/schemas/Web3SigningCredential", + "nullable": false }, "gasConfig": { "$ref": "#/components/schemas/GasTransactionConfig", "nullable": false }, - "nonce": { + "value": { "type": "string" }, "timeoutMs": { "type": "number", - "description": "The amount of milliseconds to wait for a transaction receipt beforegiving up and crashing. Only has any effect if the invocation type is SEND", + "description": "The amount of milliseconds to wait for a transaction receipt before returning an error. Only has any effect if the invocation type is SEND", "minimum": 0, "default": 60000, "nullable": false - }, - "contractJSON": { - "$ref": "#/components/schemas/ContractJSON", - "description": "For use when not using keychain, pass the contract in as this variable", - "nullable": false } } }, @@ -810,11 +644,11 @@ "WatchBlocksV1": { "type": "string", "enum": [ - "org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Subscribe", - "org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Next", - "org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Unsubscribe", - "org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Error", - "org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Complete" + "org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Subscribe", + "org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Next", + "org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Unsubscribe", + "org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Error", + "org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Complete" ], "x-enum-varnames": [ "Subscribe", @@ -1060,26 +894,43 @@ "$ref": "#/components/schemas/WatchBlocksV1BlockData" } } + }, + "ErrorExceptionResponseV1": { + "type": "object", + "description": "Error response from the connector.", + "required": ["message", "error"], + "properties": { + "message": { + "type": "string", + "description": "Short error description message.", + "nullable": false + }, + "error": { + "type": "string", + "description": "Detailed error information.", + "nullable": false + } + } } } }, "paths": { - "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode": { + "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract": { "post": { - "x-hyperledger-cactus": { + "x-hyperledger-cacti": { "http": { "verbLowerCase": "post", - "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode" + "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract" } }, - "operationId": "deployContractSolBytecodeV1", - "summary": "Deploys the bytecode of a Solidity contract.", + "operationId": "deployContract", + "summary": "Deploys the contract to ethereum ledger.", "parameters": [], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeployContractSolidityBytecodeV1Request" + "$ref": "#/components/schemas/DeployContractV1Request" } } } @@ -1090,41 +941,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeployContractSolidityBytecodeV1Response" + "$ref": "#/components/schemas/RunTransactionResponse" } } } - } - } - } - }, - "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode-json-object": { - "post": { - "x-hyperledger-cactus": { - "http": { - "verbLowerCase": "post", - "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode-json-object" - } - }, - "operationId": "deployContractSolBytecodeJsonObjectV1", - "summary": "Deploys the bytecode of a Solidity contract.", - "parameters": [], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeployContractSolidityBytecodeJsonObjectV1Request" - } - } - } - }, - "responses": { - "200": { - "description": "OK", + }, + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeployContractSolidityBytecodeV1Response" + "$ref": "#/components/schemas/ErrorExceptionResponseV1" } } } @@ -1134,7 +961,7 @@ }, "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/run-transaction": { "post": { - "x-hyperledger-cactus": { + "x-hyperledger-cacti": { "http": { "verbLowerCase": "post", "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/run-transaction" @@ -1162,13 +989,23 @@ } } } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorExceptionResponseV1" + } + } + } } } } }, "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-contract": { "post": { - "x-hyperledger-cactus": { + "x-hyperledger-cacti": { "http": { "verbLowerCase": "post", "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-contract" @@ -1196,37 +1033,13 @@ } } } - } - } - } - }, - "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-contract-json-object": { - "post": { - "x-hyperledger-cactus": { - "http": { - "verbLowerCase": "post", - "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-contract-json-object" - } - }, - "operationId": "invokeContractV1NoKeychain", - "summary": "Invokes a contract on an ethereum ledger", - "parameters": [], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InvokeContractJsonObjectV1Request" - } - } - } - }, - "responses": { - "200": { - "description": "OK", + }, + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/InvokeContractV1Response" + "$ref": "#/components/schemas/ErrorExceptionResponseV1" } } } @@ -1236,7 +1049,7 @@ }, "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics": { "get": { - "x-hyperledger-cactus": { + "x-hyperledger-cacti": { "http": { "verbLowerCase": "get", "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics" @@ -1261,7 +1074,7 @@ }, "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-raw-web3eth-method": { "post": { - "x-hyperledger-cactus": { + "x-hyperledger-cacti": { "http": { "verbLowerCase": "post", "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-raw-web3eth-method" @@ -1289,13 +1102,23 @@ } } } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorExceptionResponseV1" + } + } + } } } } }, "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-raw-web3eth-contract": { "post": { - "x-hyperledger-cactus": { + "x-hyperledger-cacti": { "http": { "verbLowerCase": "post", "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-raw-web3eth-contract" @@ -1323,6 +1146,16 @@ } } } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorExceptionResponseV1" + } + } + } } } } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/api.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/api.ts index ee2d52ee0d1..9e862ea99e9 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/api.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/api.ts @@ -1,7 +1,7 @@ /* tslint:disable */ /* eslint-disable */ /** - * Hyperledger Cactus Plugin - Connector Ethereum + * Hyperledger Cacti Plugin - Connector Ethereum * Can perform basic tasks on a Ethereum ledger * * The version of the OpenAPI document: v2.0.0-alpha.1 @@ -48,7 +48,7 @@ export interface ContractJSON { * @type {Array} * @memberof ContractJSON */ - 'abi'?: Array; + 'abi': Array; /** * * @type {string} @@ -113,125 +113,115 @@ export interface ContractJSON { /** * * @export - * @interface DeployContractSolidityBytecodeJsonObjectV1Request + * @interface ContractJsonDefinition */ -export interface DeployContractSolidityBytecodeJsonObjectV1Request { - /** - * - * @type {Web3SigningCredential} - * @memberof DeployContractSolidityBytecodeJsonObjectV1Request - */ - 'web3SigningCredential': Web3SigningCredential; - /** - * - * @type {GasTransactionConfig} - * @memberof DeployContractSolidityBytecodeJsonObjectV1Request - */ - 'gasConfig'?: GasTransactionConfig; - /** - * The amount of milliseconds to wait for a transaction receipt with theaddress of the contract(which indicates successful deployment) beforegiving up and crashing. - * @type {number} - * @memberof DeployContractSolidityBytecodeJsonObjectV1Request - */ - 'timeoutMs'?: number; +export interface ContractJsonDefinition { /** * * @type {ContractJSON} - * @memberof DeployContractSolidityBytecodeJsonObjectV1Request + * @memberof ContractJsonDefinition */ 'contractJSON': ContractJSON; - /** - * The list of arguments to pass in to the constructor of the contract being deployed. - * @type {Array} - * @memberof DeployContractSolidityBytecodeJsonObjectV1Request - */ - 'constructorArgs'?: Array; } /** * * @export - * @interface DeployContractSolidityBytecodeV1Request + * @interface ContractKeychainDefinition */ -export interface DeployContractSolidityBytecodeV1Request { +export interface ContractKeychainDefinition { /** * The contract name for retrieve the contracts json on the keychain. * @type {string} - * @memberof DeployContractSolidityBytecodeV1Request + * @memberof ContractKeychainDefinition */ 'contractName': string; /** - * The application binary interface of the solidity contract - * @type {Array} - * @memberof DeployContractSolidityBytecodeV1Request + * The keychainId for retrieve the contracts json. + * @type {string} + * @memberof ContractKeychainDefinition */ - 'contractAbi'?: Array; + 'keychainId': string; +} +/** + * + * @export + * @interface DeployContractV1Request + */ +export interface DeployContractV1Request { /** * * @type {Web3SigningCredential} - * @memberof DeployContractSolidityBytecodeV1Request + * @memberof DeployContractV1Request */ 'web3SigningCredential': Web3SigningCredential; /** - * See https://ethereum.stackexchange.com/a/47556 regarding the maximum length of the bytecode - * @type {string} - * @memberof DeployContractSolidityBytecodeV1Request + * + * @type {DeployContractV1RequestContract} + * @memberof DeployContractV1Request */ - 'bytecode'?: string; + 'contract': DeployContractV1RequestContract; /** - * The keychainId for retrieve the contracts json. - * @type {string} - * @memberof DeployContractSolidityBytecodeV1Request + * The list of arguments to pass in to the constructor of the contract being deployed. + * @type {Array} + * @memberof DeployContractV1Request */ - 'keychainId': string; + 'constructorArgs'?: Array; /** * * @type {GasTransactionConfig} - * @memberof DeployContractSolidityBytecodeV1Request + * @memberof DeployContractV1Request */ 'gasConfig'?: GasTransactionConfig; /** - * - * @type {number} - * @memberof DeployContractSolidityBytecodeV1Request + * Ether balance to send on deployment. + * @type {string} + * @memberof DeployContractV1Request */ - 'nonce'?: number; + 'value'?: string; +} +/** + * @type DeployContractV1RequestContract + * @export + */ +export type DeployContractV1RequestContract = ContractJsonDefinition | ContractKeychainDefinition; + +/** + * + * @export + * @interface DeployedContractJsonDefinition + */ +export interface DeployedContractJsonDefinition { /** * - * @type {number} - * @memberof DeployContractSolidityBytecodeV1Request - */ - 'value'?: number; - /** - * The amount of milliseconds to wait for a transaction receipt with theaddress of the contract(which indicates successful deployment) beforegiving up and crashing. - * @type {number} - * @memberof DeployContractSolidityBytecodeV1Request - */ - 'timeoutMs'?: number; - /** - * For use when not using keychain, pass the contract in as this variable - * @type {object} - * @memberof DeployContractSolidityBytecodeV1Request + * @type {ContractJSON} + * @memberof DeployedContractJsonDefinition */ - 'contractJSON'?: object; + 'contractJSON': ContractJSON; /** - * The list of arguments to pass in to the constructor of the contract being deployed. - * @type {Array} - * @memberof DeployContractSolidityBytecodeV1Request + * + * @type {string} + * @memberof DeployedContractJsonDefinition */ - 'constructorArgs'?: Array; + 'contractAddress': string; } /** - * + * Error response from the connector. * @export - * @interface DeployContractSolidityBytecodeV1Response + * @interface ErrorExceptionResponseV1 */ -export interface DeployContractSolidityBytecodeV1Response { +export interface ErrorExceptionResponseV1 { /** - * - * @type {Web3TransactionReceipt} - * @memberof DeployContractSolidityBytecodeV1Response + * Short error description message. + * @type {string} + * @memberof ErrorExceptionResponseV1 */ - 'transactionReceipt': Web3TransactionReceipt; + 'message': string; + /** + * Detailed error information. + * @type {string} + * @memberof ErrorExceptionResponseV1 + */ + 'error': string; } /** * @@ -366,114 +356,39 @@ export interface GasTransactionConfigLegacy { /** * * @export - * @interface InvokeContractJsonObjectV1Request + * @interface InvokeContractV1Request */ -export interface InvokeContractJsonObjectV1Request { - /** - * - * @type {Web3SigningCredential} - * @memberof InvokeContractJsonObjectV1Request - */ - 'web3SigningCredential': Web3SigningCredential; +export interface InvokeContractV1Request { /** * - * @type {EthContractInvocationType} - * @memberof InvokeContractJsonObjectV1Request + * @type {InvokeContractV1RequestContract} + * @memberof InvokeContractV1Request */ - 'invocationType': EthContractInvocationType; + 'contract': InvokeContractV1RequestContract; /** * The name of the contract method to invoke. * @type {string} - * @memberof InvokeContractJsonObjectV1Request + * @memberof InvokeContractV1Request */ 'methodName': string; /** * The list of arguments to pass in to the contract method being invoked. * @type {Array} - * @memberof InvokeContractJsonObjectV1Request - */ - 'params': Array; - /** - * Address of the solidity contract - * @type {string} - * @memberof InvokeContractJsonObjectV1Request - */ - 'contractAddress': string; - /** - * - * @type {string} - * @memberof InvokeContractJsonObjectV1Request - */ - 'value'?: string; - /** - * - * @type {GasTransactionConfig} - * @memberof InvokeContractJsonObjectV1Request - */ - 'gasConfig'?: GasTransactionConfig; - /** - * - * @type {string} - * @memberof InvokeContractJsonObjectV1Request - */ - 'nonce'?: string; - /** - * The amount of milliseconds to wait for a transaction receipt beforegiving up and crashing. Only has any effect if the invocation type is SEND - * @type {number} - * @memberof InvokeContractJsonObjectV1Request - */ - 'timeoutMs'?: number; - /** - * - * @type {ContractJSON} - * @memberof InvokeContractJsonObjectV1Request - */ - 'contractJSON': ContractJSON; -} - - -/** - * - * @export - * @interface InvokeContractV1Request - */ -export interface InvokeContractV1Request { - /** - * The contract name to find it in the keychain plugin - * @type {string} * @memberof InvokeContractV1Request */ - 'contractName': string; - /** - * - * @type {Web3SigningCredential} - * @memberof InvokeContractV1Request - */ - 'web3SigningCredential': Web3SigningCredential; + 'params': Array; /** * * @type {EthContractInvocationType} * @memberof InvokeContractV1Request */ 'invocationType': EthContractInvocationType; - /** - * The name of the contract method to invoke. - * @type {string} - * @memberof InvokeContractV1Request - */ - 'methodName': string; - /** - * The list of arguments to pass in to the contract method being invoked. - * @type {Array} - * @memberof InvokeContractV1Request - */ - 'params': Array; /** * - * @type {string} + * @type {Web3SigningCredential} * @memberof InvokeContractV1Request */ - 'value'?: string; + 'web3SigningCredential'?: Web3SigningCredential; /** * * @type {GasTransactionConfig} @@ -485,22 +400,22 @@ export interface InvokeContractV1Request { * @type {string} * @memberof InvokeContractV1Request */ - 'nonce'?: string; + 'value'?: string; /** - * The amount of milliseconds to wait for a transaction receipt beforegiving up and crashing. Only has any effect if the invocation type is SEND + * The amount of milliseconds to wait for a transaction receipt before returning an error. Only has any effect if the invocation type is SEND * @type {number} * @memberof InvokeContractV1Request */ 'timeoutMs'?: number; - /** - * The keychainId for retrieve the contracts json. - * @type {string} - * @memberof InvokeContractV1Request - */ - 'keychainId': string; } +/** + * @type InvokeContractV1RequestContract + * @export + */ +export type InvokeContractV1RequestContract = ContractKeychainDefinition | DeployedContractJsonDefinition; + /** * * @export @@ -678,138 +593,6 @@ export interface RunTransactionResponse { */ 'transactionReceipt': Web3TransactionReceipt; } -/** - * - * @export - * @interface SolidityContractJsonArtifact - */ -export interface SolidityContractJsonArtifact { - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifact - */ - 'contractName': string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifact - */ - 'metadata'?: string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifact - */ - 'bytecode'?: string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifact - */ - 'deployedBytecode'?: string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifact - */ - 'sourceMap'?: string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifact - */ - 'deployedSourceMap'?: string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifact - */ - 'sourcePath'?: string; - /** - * - * @type {SolidityContractJsonArtifactCompiler} - * @memberof SolidityContractJsonArtifact - */ - 'compiler'?: SolidityContractJsonArtifactCompiler; - /** - * - * @type {{ [key: string]: any; }} - * @memberof SolidityContractJsonArtifact - */ - 'functionHashes'?: { [key: string]: any; }; - /** - * - * @type {SolidityContractJsonArtifactGasEstimates} - * @memberof SolidityContractJsonArtifact - */ - 'gasEstimates'?: SolidityContractJsonArtifactGasEstimates; -} -/** - * - * @export - * @interface SolidityContractJsonArtifactCompiler - */ -export interface SolidityContractJsonArtifactCompiler { - [key: string]: any; - - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifactCompiler - */ - 'name'?: string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifactCompiler - */ - 'version'?: string; -} -/** - * - * @export - * @interface SolidityContractJsonArtifactGasEstimates - */ -export interface SolidityContractJsonArtifactGasEstimates { - /** - * - * @type {SolidityContractJsonArtifactGasEstimatesCreation} - * @memberof SolidityContractJsonArtifactGasEstimates - */ - 'creation'?: SolidityContractJsonArtifactGasEstimatesCreation; - /** - * - * @type {{ [key: string]: any; }} - * @memberof SolidityContractJsonArtifactGasEstimates - */ - 'external'?: { [key: string]: any; }; -} -/** - * - * @export - * @interface SolidityContractJsonArtifactGasEstimatesCreation - */ -export interface SolidityContractJsonArtifactGasEstimatesCreation { - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifactGasEstimatesCreation - */ - 'codeDepositCost'?: string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifactGasEstimatesCreation - */ - 'executionCost'?: string; - /** - * - * @type {string} - * @memberof SolidityContractJsonArtifactGasEstimatesCreation - */ - 'totalCost'?: string; -} /** * * @export @@ -817,11 +600,11 @@ export interface SolidityContractJsonArtifactGasEstimatesCreation { */ export const WatchBlocksV1 = { - Subscribe: 'org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Subscribe', - Next: 'org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Next', - Unsubscribe: 'org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Unsubscribe', - Error: 'org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Error', - Complete: 'org.hyperledger.cactus.api.async.ethereum.WatchBlocksV1.Complete' + Subscribe: 'org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Subscribe', + Next: 'org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Next', + Unsubscribe: 'org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Unsubscribe', + Error: 'org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Error', + Complete: 'org.hyperledger.cacti.api.async.ethereum.WatchBlocksV1.Complete' } as const; export type WatchBlocksV1 = typeof WatchBlocksV1[keyof typeof WatchBlocksV1]; @@ -1099,36 +882,36 @@ export interface Web3BlockHeader { * @type Web3SigningCredential * @export */ -export type Web3SigningCredential = Web3SigningCredentialCactusKeychainRef | Web3SigningCredentialGethKeychainPassword | Web3SigningCredentialNone | Web3SigningCredentialPrivateKeyHex; +export type Web3SigningCredential = Web3SigningCredentialCactiKeychainRef | Web3SigningCredentialGethKeychainPassword | Web3SigningCredentialNone | Web3SigningCredentialPrivateKeyHex; /** * * @export - * @interface Web3SigningCredentialCactusKeychainRef + * @interface Web3SigningCredentialCactiKeychainRef */ -export interface Web3SigningCredentialCactusKeychainRef { +export interface Web3SigningCredentialCactiKeychainRef { /** * * @type {Web3SigningCredentialType} - * @memberof Web3SigningCredentialCactusKeychainRef + * @memberof Web3SigningCredentialCactiKeychainRef */ 'type': Web3SigningCredentialType; /** * The ethereum account (public key) that the credential belongs to. Basically the username in the traditional terminology of authentication. * @type {string} - * @memberof Web3SigningCredentialCactusKeychainRef + * @memberof Web3SigningCredentialCactiKeychainRef */ 'ethAccount': string; /** * The key to use when looking up the the keychain entry holding the secret pointed to by the keychainEntryKey parameter. * @type {string} - * @memberof Web3SigningCredentialCactusKeychainRef + * @memberof Web3SigningCredentialCactiKeychainRef */ 'keychainEntryKey': string; /** * The keychain ID to use when looking up the the keychain plugin instance that will be used to retrieve the secret pointed to by the keychainEntryKey parameter. * @type {string} - * @memberof Web3SigningCredentialCactusKeychainRef + * @memberof Web3SigningCredentialCactiKeychainRef */ 'keychainId'?: string; } @@ -1210,7 +993,7 @@ export interface Web3SigningCredentialPrivateKeyHex { */ export const Web3SigningCredentialType = { - CactusKeychainRef: 'CACTUS_KEYCHAIN_REF', + CactiKeychainRef: 'CACTI_KEYCHAIN_REF', GethKeychainPassword: 'GETH_KEYCHAIN_PASSWORD', PrivateKeyHex: 'PRIVATE_KEY_HEX', None: 'NONE' @@ -1442,47 +1225,13 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati return { /** * - * @summary Deploys the bytecode of a Solidity contract. - * @param {DeployContractSolidityBytecodeJsonObjectV1Request} [deployContractSolidityBytecodeJsonObjectV1Request] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - deployContractSolBytecodeJsonObjectV1: async (deployContractSolidityBytecodeJsonObjectV1Request?: DeployContractSolidityBytecodeJsonObjectV1Request, options: AxiosRequestConfig = {}): Promise => { - const localVarPath = `/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode-json-object`; - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - - - localVarHeaderParameter['Content-Type'] = 'application/json'; - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(deployContractSolidityBytecodeJsonObjectV1Request, localVarRequestOptions, configuration) - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, - /** - * - * @summary Deploys the bytecode of a Solidity contract. - * @param {DeployContractSolidityBytecodeV1Request} [deployContractSolidityBytecodeV1Request] + * @summary Deploys the contract to ethereum ledger. + * @param {DeployContractV1Request} [deployContractV1Request] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - deployContractSolBytecodeV1: async (deployContractSolidityBytecodeV1Request?: DeployContractSolidityBytecodeV1Request, options: AxiosRequestConfig = {}): Promise => { - const localVarPath = `/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode`; + deployContract: async (deployContractV1Request?: DeployContractV1Request, options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -1501,7 +1250,7 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(deployContractSolidityBytecodeV1Request, localVarRequestOptions, configuration) + localVarRequestOptions.data = serializeDataIfNeeded(deployContractV1Request, localVarRequestOptions, configuration) return { url: toPathString(localVarUrlObj), @@ -1572,40 +1321,6 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati options: localVarRequestOptions, }; }, - /** - * - * @summary Invokes a contract on an ethereum ledger - * @param {InvokeContractJsonObjectV1Request} [invokeContractJsonObjectV1Request] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - invokeContractV1NoKeychain: async (invokeContractJsonObjectV1Request?: InvokeContractJsonObjectV1Request, options: AxiosRequestConfig = {}): Promise => { - const localVarPath = `/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-contract-json-object`; - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - - - localVarHeaderParameter['Content-Type'] = 'application/json'; - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(invokeContractJsonObjectV1Request, localVarRequestOptions, configuration) - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, /** * * @summary Low-level endpoint to invoke a method on deployed contract. @@ -1720,24 +1435,13 @@ export const DefaultApiFp = function(configuration?: Configuration) { return { /** * - * @summary Deploys the bytecode of a Solidity contract. - * @param {DeployContractSolidityBytecodeJsonObjectV1Request} [deployContractSolidityBytecodeJsonObjectV1Request] + * @summary Deploys the contract to ethereum ledger. + * @param {DeployContractV1Request} [deployContractV1Request] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async deployContractSolBytecodeJsonObjectV1(deployContractSolidityBytecodeJsonObjectV1Request?: DeployContractSolidityBytecodeJsonObjectV1Request, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.deployContractSolBytecodeJsonObjectV1(deployContractSolidityBytecodeJsonObjectV1Request, options); - return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); - }, - /** - * - * @summary Deploys the bytecode of a Solidity contract. - * @param {DeployContractSolidityBytecodeV1Request} [deployContractSolidityBytecodeV1Request] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - async deployContractSolBytecodeV1(deployContractSolidityBytecodeV1Request?: DeployContractSolidityBytecodeV1Request, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.deployContractSolBytecodeV1(deployContractSolidityBytecodeV1Request, options); + async deployContract(deployContractV1Request?: DeployContractV1Request, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deployContract(deployContractV1Request, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -1761,17 +1465,6 @@ export const DefaultApiFp = function(configuration?: Configuration) { const localVarAxiosArgs = await localVarAxiosParamCreator.invokeContractV1(invokeContractV1Request, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, - /** - * - * @summary Invokes a contract on an ethereum ledger - * @param {InvokeContractJsonObjectV1Request} [invokeContractJsonObjectV1Request] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - async invokeContractV1NoKeychain(invokeContractJsonObjectV1Request?: InvokeContractJsonObjectV1Request, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.invokeContractV1NoKeychain(invokeContractJsonObjectV1Request, options); - return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); - }, /** * * @summary Low-level endpoint to invoke a method on deployed contract. @@ -1817,23 +1510,13 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa return { /** * - * @summary Deploys the bytecode of a Solidity contract. - * @param {DeployContractSolidityBytecodeJsonObjectV1Request} [deployContractSolidityBytecodeJsonObjectV1Request] + * @summary Deploys the contract to ethereum ledger. + * @param {DeployContractV1Request} [deployContractV1Request] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - deployContractSolBytecodeJsonObjectV1(deployContractSolidityBytecodeJsonObjectV1Request?: DeployContractSolidityBytecodeJsonObjectV1Request, options?: any): AxiosPromise { - return localVarFp.deployContractSolBytecodeJsonObjectV1(deployContractSolidityBytecodeJsonObjectV1Request, options).then((request) => request(axios, basePath)); - }, - /** - * - * @summary Deploys the bytecode of a Solidity contract. - * @param {DeployContractSolidityBytecodeV1Request} [deployContractSolidityBytecodeV1Request] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - deployContractSolBytecodeV1(deployContractSolidityBytecodeV1Request?: DeployContractSolidityBytecodeV1Request, options?: any): AxiosPromise { - return localVarFp.deployContractSolBytecodeV1(deployContractSolidityBytecodeV1Request, options).then((request) => request(axios, basePath)); + deployContract(deployContractV1Request?: DeployContractV1Request, options?: any): AxiosPromise { + return localVarFp.deployContract(deployContractV1Request, options).then((request) => request(axios, basePath)); }, /** * @@ -1854,16 +1537,6 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa invokeContractV1(invokeContractV1Request?: InvokeContractV1Request, options?: any): AxiosPromise { return localVarFp.invokeContractV1(invokeContractV1Request, options).then((request) => request(axios, basePath)); }, - /** - * - * @summary Invokes a contract on an ethereum ledger - * @param {InvokeContractJsonObjectV1Request} [invokeContractJsonObjectV1Request] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - invokeContractV1NoKeychain(invokeContractJsonObjectV1Request?: InvokeContractJsonObjectV1Request, options?: any): AxiosPromise { - return localVarFp.invokeContractV1NoKeychain(invokeContractJsonObjectV1Request, options).then((request) => request(axios, basePath)); - }, /** * * @summary Low-level endpoint to invoke a method on deployed contract. @@ -1906,26 +1579,14 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa export class DefaultApi extends BaseAPI { /** * - * @summary Deploys the bytecode of a Solidity contract. - * @param {DeployContractSolidityBytecodeJsonObjectV1Request} [deployContractSolidityBytecodeJsonObjectV1Request] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - * @memberof DefaultApi - */ - public deployContractSolBytecodeJsonObjectV1(deployContractSolidityBytecodeJsonObjectV1Request?: DeployContractSolidityBytecodeJsonObjectV1Request, options?: AxiosRequestConfig) { - return DefaultApiFp(this.configuration).deployContractSolBytecodeJsonObjectV1(deployContractSolidityBytecodeJsonObjectV1Request, options).then((request) => request(this.axios, this.basePath)); - } - - /** - * - * @summary Deploys the bytecode of a Solidity contract. - * @param {DeployContractSolidityBytecodeV1Request} [deployContractSolidityBytecodeV1Request] + * @summary Deploys the contract to ethereum ledger. + * @param {DeployContractV1Request} [deployContractV1Request] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApi */ - public deployContractSolBytecodeV1(deployContractSolidityBytecodeV1Request?: DeployContractSolidityBytecodeV1Request, options?: AxiosRequestConfig) { - return DefaultApiFp(this.configuration).deployContractSolBytecodeV1(deployContractSolidityBytecodeV1Request, options).then((request) => request(this.axios, this.basePath)); + public deployContract(deployContractV1Request?: DeployContractV1Request, options?: AxiosRequestConfig) { + return DefaultApiFp(this.configuration).deployContract(deployContractV1Request, options).then((request) => request(this.axios, this.basePath)); } /** @@ -1951,18 +1612,6 @@ export class DefaultApi extends BaseAPI { return DefaultApiFp(this.configuration).invokeContractV1(invokeContractV1Request, options).then((request) => request(this.axios, this.basePath)); } - /** - * - * @summary Invokes a contract on an ethereum ledger - * @param {InvokeContractJsonObjectV1Request} [invokeContractJsonObjectV1Request] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - * @memberof DefaultApi - */ - public invokeContractV1NoKeychain(invokeContractJsonObjectV1Request?: InvokeContractJsonObjectV1Request, options?: AxiosRequestConfig) { - return DefaultApiFp(this.configuration).invokeContractV1NoKeychain(invokeContractJsonObjectV1Request, options).then((request) => request(this.axios, this.basePath)); - } - /** * * @summary Low-level endpoint to invoke a method on deployed contract. diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/base.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/base.ts index 90d9122acd6..e45d2a28832 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/base.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/base.ts @@ -1,7 +1,7 @@ /* tslint:disable */ /* eslint-disable */ /** - * Hyperledger Cactus Plugin - Connector Ethereum + * Hyperledger Cacti Plugin - Connector Ethereum * Can perform basic tasks on a Ethereum ledger * * The version of the OpenAPI document: v2.0.0-alpha.1 diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/common.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/common.ts index 3d261b26b7c..213d22e2db3 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/common.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/common.ts @@ -1,7 +1,7 @@ /* tslint:disable */ /* eslint-disable */ /** - * Hyperledger Cactus Plugin - Connector Ethereum + * Hyperledger Cacti Plugin - Connector Ethereum * Can perform basic tasks on a Ethereum ledger * * The version of the OpenAPI document: v2.0.0-alpha.1 diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/configuration.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/configuration.ts index 76d3db5b830..8e8f0ce3021 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/configuration.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/configuration.ts @@ -1,7 +1,7 @@ /* tslint:disable */ /* eslint-disable */ /** - * Hyperledger Cactus Plugin - Connector Ethereum + * Hyperledger Cacti Plugin - Connector Ethereum * Can perform basic tasks on a Ethereum ledger * * The version of the OpenAPI document: v2.0.0-alpha.1 diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/index.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/index.ts index 00c54cf92aa..4edb8dc052a 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/index.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/generated/openapi/typescript-axios/index.ts @@ -1,7 +1,7 @@ /* tslint:disable */ /* eslint-disable */ /** - * Hyperledger Cactus Plugin - Connector Ethereum + * Hyperledger Cacti Plugin - Connector Ethereum * Can perform basic tasks on a Ethereum ledger * * The version of the OpenAPI document: v2.0.0-alpha.1 diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/plugin-ledger-connector-ethereum.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/plugin-ledger-connector-ethereum.ts index 3de5c20500f..593eb7f9b20 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/plugin-ledger-connector-ethereum.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/plugin-ledger-connector-ethereum.ts @@ -37,22 +37,18 @@ import { LogLevelDesc, } from "@hyperledger/cactus-common"; -import { DeployContractSolidityBytecodeEndpoint } from "./web-services/deploy-contract-solidity-bytecode-endpoint"; -import { DeployContractSolidityBytecodeJsonObjectEndpoint } from "./web-services/deploy-contract-solidity-bytecode-endpoint-json-object"; +import { DeployContractEndpoint } from "./web-services/deploy-contract-v1-endpoint"; import { - DeployContractSolidityBytecodeV1Request, - DeployContractSolidityBytecodeJsonObjectV1Request, - DeployContractSolidityBytecodeV1Response, + DeployContractV1Request, EthContractInvocationType, EthContractInvocationWeb3Method, InvokeContractV1Request, - InvokeContractJsonObjectV1Request, InvokeContractV1Response, RunTransactionRequest, RunTransactionResponse, Web3SigningCredentialGethKeychainPassword, - Web3SigningCredentialCactusKeychainRef, + Web3SigningCredentialCactiKeychainRef, Web3SigningCredentialPrivateKeyHex, Web3SigningCredentialType, WatchBlocksV1, @@ -60,17 +56,22 @@ import { InvokeRawWeb3EthMethodV1Request, InvokeRawWeb3EthContractV1Request, EthereumTransactionConfig, + ContractKeychainDefinition, + GasTransactionConfig, + ContractJSON, } from "./generated/openapi/typescript-axios"; -import { RunTransactionEndpoint } from "./web-services/run-transaction-endpoint"; -import { InvokeContractEndpoint } from "./web-services/invoke-contract-endpoint"; -import { InvokeContractJsonObjectEndpoint } from "./web-services/invoke-contract-endpoint-json-object"; +import { RunTransactionEndpoint } from "./web-services/run-transaction-v1-endpoint"; +import { InvokeContractEndpoint } from "./web-services/invoke-contract-v1-endpoint"; import { WatchBlocksV1Endpoint } from "./web-services/watch-blocks-v1-endpoint"; -import { GetPrometheusExporterMetricsEndpointV1 } from "./web-services/get-prometheus-exporter-metrics-endpoint-v1"; +import { GetPrometheusExporterMetricsEndpointV1 } from "./web-services/get-prometheus-exporter-metrics-v1-endpoint"; import { InvokeRawWeb3EthMethodEndpoint } from "./web-services/invoke-raw-web3eth-method-v1-endpoint"; import { InvokeRawWeb3EthContractEndpoint } from "./web-services/invoke-raw-web3eth-contract-v1-endpoint"; import { + isContractJsonDefinition, + isContractKeychainDefinition, + isDeployedContractJsonDefinition, isGasTransactionConfigEIP1559, isGasTransactionConfigLegacy, isWeb3SigningCredentialNone, @@ -85,6 +86,16 @@ import { // Used when waiting for WS requests to be send correctly before disconnecting const waitForWsProviderRequestsTimeout = 5 * 1000; // 5s const waitForWsProviderRequestsStep = 500; // 500ms +type RunContractDeploymentInput = { + web3SigningCredential: + | Web3SigningCredentialCactiKeychainRef + | Web3SigningCredentialGethKeychainPassword + | Web3SigningCredentialPrivateKeyHex; + contractJSON: ContractJSON; + gasConfig?: GasTransactionConfig; + constructorArgs?: unknown[]; + value?: string; +}; export interface IPluginLedgerConnectorEthereumOptions extends ICactusPluginOptions { @@ -98,8 +109,8 @@ export interface IPluginLedgerConnectorEthereumOptions export class PluginLedgerConnectorEthereum implements IPluginLedgerConnector< - DeployContractSolidityBytecodeV1Request, - DeployContractSolidityBytecodeV1Response, + DeployContractV1Request, + RunTransactionResponse, RunTransactionRequest, RunTransactionResponse >, @@ -276,14 +287,7 @@ export class PluginLedgerConnectorEthereum } const endpoints: IWebServiceEndpoint[] = []; { - const endpoint = new DeployContractSolidityBytecodeEndpoint({ - connector: this, - logLevel: this.options.logLevel, - }); - endpoints.push(endpoint); - } - { - const endpoint = new DeployContractSolidityBytecodeJsonObjectEndpoint({ + const endpoint = new DeployContractEndpoint({ connector: this, logLevel: this.options.logLevel, }); @@ -303,13 +307,6 @@ export class PluginLedgerConnectorEthereum }); endpoints.push(endpoint); } - { - const endpoint = new InvokeContractJsonObjectEndpoint({ - connector: this, - logLevel: this.options.logLevel, - }); - endpoints.push(endpoint); - } { const endpoint = new GetPrometheusExporterMetricsEndpointV1({ connector: this, @@ -407,27 +404,82 @@ export class PluginLedgerConnectorEthereum return this.isSafeToCallObjectMethod(contract.methods, name); } - public async getContractInfoKeychain( + /** + * Simple function for estimating `maxFeePerGas` to sent with transaction. + * @warn It's not optimized for either speed or cost, consider using more complex solution on production! + * @param priorityFee what priority tip you plan to include. + * @returns estimated `maxFeePerGas` value. + */ + public async estimateMaxFeePerGas( + priorityFee: number | string = 0, + ): Promise { + const pendingBlock = await this.web3.eth.getBlock("pending"); + const baseFee = pendingBlock.baseFeePerGas; + if (!baseFee) { + throw new Error( + "Can't estimate maxFeePerGas - could not get recent baseFeePerGas", + ); + } + const estimate = baseFee + BigInt(priorityFee); + return estimate.toString(); + } + + //////////////////////////// + // Invoke + //////////////////////////// + + /** + * Invoke contract method. + * + * @param req contract method and transaction definition + * @returns transaction receipt + */ + public async invokeContract( req: InvokeContractV1Request, ): Promise { - const fnTag = `${this.className}#invokeContract()`; + Checks.truthy(req, "invokeContract() request arg"); - const { contractName, keychainId } = req; - if (!contractName) { + if (isDeployedContractJsonDefinition(req.contract)) { + return this.runContractInvoke( + req, + req.contract.contractAddress, + req.contract.contractJSON, + ); + } else if (isContractKeychainDefinition(req.contract)) { + return this.invokeContractFromKeychain(req, req.contract); + } else { + // Exhaustive check + const unknownContract: never = req.contract; throw new Error( - `${fnTag} Cannot recover the keychain plugin because the contractName is empty`, + `Unknown contract definition provided: ${unknownContract}`, ); } - if (!keychainId) { - throw new Error(`${fnTag} Cannot invoke contract without keychainId`); - } - const keychainPlugin = this.pluginRegistry.findOneByKeychainId(keychainId); - if (!keychainPlugin.has(contractName)) { + } + + /** + * Invoke contract method using contract instance stored in a kechain plugin. + * + * @param req contract method and transaction definition + * @param contract contract keychain reference + * @returns transaction receipt + */ + private async invokeContractFromKeychain( + req: InvokeContractV1Request, + contract: ContractKeychainDefinition, + ): Promise { + const fnTag = `${this.className}#invokeContract()`; + Checks.truthy(contract.contractName, `${fnTag} contractName arg`); + Checks.truthy(contract.keychainId, `${fnTag} keychainId arg`); + + const keychainPlugin = this.pluginRegistry.findOneByKeychainId( + contract.keychainId, + ); + if (!keychainPlugin.has(contract.contractName)) { throw new Error( `${fnTag} Cannot invoke the contract because contractName is not in the keychainPlugin`, ); } - const contractStr = await keychainPlugin.get(contractName); + const contractStr = await keychainPlugin.get(contract.contractName); const contractJSON = JSON.parse(contractStr); // if not exists a contract deployed, we deploy it @@ -437,67 +489,40 @@ export class PluginLedgerConnectorEthereum !contractJSON.networks[networkId] || !contractJSON.networks[networkId].address ) { - if (isWeb3SigningCredentialNone(req.web3SigningCredential)) { - throw new Error(`${fnTag} Cannot deploy contract with pre-signed TX`); - } - - const receipt = await this.runDeploy(req); - - const address = { - address: receipt.transactionReceipt.contractAddress, - }; - const network = { [networkId]: address }; - contractJSON.networks = network; - keychainPlugin.set(req.contractName, JSON.stringify(contractJSON)); + throw new Error( + `Contract has not been deployed yet on this network (id ${networkId}) - can't invoke!`, + ); } - return this.invokeContract({ - ...req, - contractAddress: contractJSON.networks[networkId].address, - contractJSON: contractJSON, - }); - } - - public async getContractInfo( - req: InvokeContractJsonObjectV1Request, - ): Promise { - const fnTag = `${this.className}#invokeContractNoKeychain()`; - const { contractJSON, contractAddress } = req; - if (!contractJSON) { - throw new Error(`${fnTag} The contractJson param is needed`); - } - if (!contractAddress) { - throw new Error(`${fnTag} The contractAddress param is needed`); - } - return this.invokeContract(req); + return this.runContractInvoke( + req, + contractJSON.networks[networkId].address, + contractJSON, + ); } /** - * Simple function for estimating `maxFeePerGas` to sent with transaction. - * @warn It's not optimized for either speed or cost, consider using more complex solution on production! - * @param priorityFee what priority tip you plan to include. - * @returns estimated `maxFeePerGas` value. + * Internal logic for invoking actual transaction given address and ABI. + * + * @param req contract method and transaction definition + * @param contractAddress deployed contract address + * @param contractJSON contract ABI and bytecode + * @returns transaction receipt */ - public async estimateMaxFeePerGas( - priorityFee: number | string = 0, - ): Promise { - const pendingBlock = await this.web3.eth.getBlock("pending"); - const baseFee = pendingBlock.baseFeePerGas; - if (!baseFee) { - throw new Error( - "Can't estimate maxFeePerGas - could not get recent baseFeePerGas", - ); - } - const estimate = baseFee + BigInt(priorityFee); - return estimate.toString(); - } - - public async invokeContract( - req: InvokeContractJsonObjectV1Request, + private async runContractInvoke( + req: InvokeContractV1Request, + contractAddress: string, + contractJSON: ContractJSON, ): Promise { - const fnTag = `${this.className}#invokeContract()`; + const fnTag = `${this.className}#runContractInvoke()`; + Checks.truthy(req, "runContractInvoke() contractAddress arg"); + Checks.truthy(req, "runContractInvoke() contractJSON arg"); - const { contractAddress, contractJSON } = req; + if (!req.web3SigningCredential) { + req.web3SigningCredential = { + type: Web3SigningCredentialType.None, + }; + } let abi; if (contractJSON.abi) { @@ -511,7 +536,6 @@ export class PluginLedgerConnectorEthereum } const contractInstance = new this.web3.eth.Contract(abi, contractAddress); - const isSafeToCall = await this.isSafeToCallContractMethod( contractInstance, req.methodName, @@ -539,14 +563,13 @@ export class PluginLedgerConnectorEthereum } const web3SigningCredential = req.web3SigningCredential as | Web3SigningCredentialPrivateKeyHex - | Web3SigningCredentialCactusKeychainRef; + | Web3SigningCredentialCactiKeychainRef; const transactionConfig = { from: web3SigningCredential.ethAccount, to: contractAddress, gasConfig: req.gasConfig, value: req.value, - nonce: req.nonce, data: method.encodeABI(), }; @@ -565,50 +588,60 @@ export class PluginLedgerConnectorEthereum } } + //////////////////////////// + // Transact + //////////////////////////// + + /** + * Send ethereum transaction. + * + * @param req transaction definition. + * @returns transaction receipt. + */ public async transact( req: RunTransactionRequest, ): Promise { const fnTag = `${this.className}#transact()`; - try { - switch (req.web3SigningCredential.type) { - case Web3SigningCredentialType.CactusKeychainRef: { - return await this.transactCactusKeychainRef(req); - } - case Web3SigningCredentialType.GethKeychainPassword: { - return await this.transactGethKeychain(req); - } - case Web3SigningCredentialType.PrivateKeyHex: { - return await this.transactPrivateKey(req); - } - case Web3SigningCredentialType.None: { - if (req.transactionConfig.rawTransaction) { - return await this.transactSigned( - req.transactionConfig.rawTransaction, - ); - } else { - throw new Error( - `${fnTag} Expected pre-signed raw transaction ` + - ` since signing credential is specified as` + - `Web3SigningCredentialType.NONE`, - ); - } - } - default: { + + switch (req.web3SigningCredential.type) { + case Web3SigningCredentialType.CactiKeychainRef: { + return await this.transactCactiKeychainRef(req); + } + case Web3SigningCredentialType.GethKeychainPassword: { + return await this.transactGethKeychain(req); + } + case Web3SigningCredentialType.PrivateKeyHex: { + return await this.transactPrivateKey(req); + } + case Web3SigningCredentialType.None: { + if (req.transactionConfig.rawTransaction) { + return await this.transactSigned( + req.transactionConfig.rawTransaction, + ); + } else { throw new Error( - `${fnTag} Unrecognized Web3SigningCredentialType: ` + - `${req.web3SigningCredential.type} Supported ones are: ` + - `${Object.values(Web3SigningCredentialType).join(";")}`, + `${fnTag} Expected pre-signed raw transaction ` + + ` since signing credential is specified as` + + `Web3SigningCredentialType.NONE`, ); } } - } catch (error) { - if ("toJSON" in error) { - this.log.debug("transact() failed with error:", error.toJSON()); + default: { + throw new Error( + `${fnTag} Unrecognized Web3SigningCredentialType: ` + + `${req.web3SigningCredential.type} Supported ones are: ` + + `${Object.values(Web3SigningCredentialType).join(";")}`, + ); } - throw error; } } + /** + * Send already signed transaction. + * + * @param rawTransaction signed transaction payload. + * @returns transaction receipt. + */ public async transactSigned( rawTransaction: string, ): Promise { @@ -626,7 +659,51 @@ export class PluginLedgerConnectorEthereum }; } - public async transactGethKeychain( + /** + * Wait until receipt for transaction with specified hash is returned. + * Throws if timeout expires. + * + * @param txHash sent transaction hash + * @param timeoutMs timeout in miliseconds + * @returns transaction receipt. + */ + public async pollForTxReceipt( + txHash: string, + timeoutMs = 60000, + ): Promise> { + const fnTag = `${this.className}#pollForTxReceipt()`; + let timedOut = false; + let tries = 0; + const startedAt = new Date(); + + do { + try { + return (await this.web3.eth.getTransactionReceipt( + txHash, + Web3StringReturnFormat, + )) as TransactionReceiptBase; + } catch (error) { + this.log.debug( + "pollForTxReceipt getTransactionReceipt failed - (retry)", + ); + } + + // Sleep for 1 second + await new Promise((resolve) => setTimeout(resolve, 1000)); + tries++; + timedOut = Date.now() >= startedAt.getTime() + timeoutMs; + } while (!timedOut); + + throw new Error(`${fnTag} Timed out ${timeoutMs}ms, polls=${tries}`); + } + + /** + * Transact with identity stored in Geth node. + * + * @param txIn transaction definition. + * @returns transaction receipt. + */ + private async transactGethKeychain( txIn: RunTransactionRequest, ): Promise { const fnTag = `${this.className}#transactGethKeychain()`; @@ -654,7 +731,13 @@ export class PluginLedgerConnectorEthereum } } - public async transactPrivateKey( + /** + * Transact with private key passed in argument. + * + * @param req transaction definition. + * @returns transaction receipt. + */ + private async transactPrivateKey( req: RunTransactionRequest, ): Promise { const fnTag = `${this.className}#transactPrivateKey()`; @@ -677,13 +760,19 @@ export class PluginLedgerConnectorEthereum } } - public async transactCactusKeychainRef( + /** + * Transact with identity stored in cacti keychain. + * + * @param req transaction definition. + * @returns transaction receipt. + */ + private async transactCactiKeychainRef( req: RunTransactionRequest, ): Promise { - const fnTag = `${this.className}#transactCactusKeychainRef()`; + const fnTag = `${this.className}#transactCactiKeychainRef()`; const { transactionConfig, web3SigningCredential } = req; const { ethAccount, keychainEntryKey, keychainId } = - web3SigningCredential as Web3SigningCredentialCactusKeychainRef; + web3SigningCredential as Web3SigningCredentialCactiKeychainRef; // locate the keychain plugin that has access to the keychain backend // denoted by the keychainID from the request. @@ -706,136 +795,201 @@ export class PluginLedgerConnectorEthereum }); } - public async pollForTxReceipt( - txHash: string, - timeoutMs = 60000, - ): Promise> { - const fnTag = `${this.className}#pollForTxReceipt()`; - let timedOut = false; - let tries = 0; - const startedAt = new Date(); + /** + * Convert connector transaction config to web3js transaction object. + * + * @param txConfig connector transaction config + * @returns web3js transaction + */ + private async getTransactionFromTxConfig( + txConfig: EthereumTransactionConfig, + ): Promise { + const tx: Transaction = { + from: txConfig.from, + to: txConfig.to, + value: txConfig.value, + nonce: txConfig.nonce, + data: txConfig.data, + }; - do { - try { - return (await this.web3.eth.getTransactionReceipt( - txHash, - Web3StringReturnFormat, - )) as TransactionReceiptBase; - } catch (error) { - this.log.debug( - "pollForTxReceipt getTransactionReceipt failed - (retry)", - ); + // Apply gas config to the transaction + if (txConfig.gasConfig) { + if (isGasTransactionConfigLegacy(txConfig.gasConfig)) { + if (isGasTransactionConfigEIP1559(txConfig.gasConfig)) { + throw new RuntimeError( + `Detected mixed gasConfig! Use either legacy or EIP-1559 mode. gasConfig - ${JSON.stringify( + txConfig.gasConfig, + )}`, + ); + } + tx.maxPriorityFeePerGas = txConfig.gasConfig.gasPrice; + tx.maxFeePerGas = txConfig.gasConfig.gasPrice; + tx.gasLimit = txConfig.gasConfig.gas; + } else { + tx.maxPriorityFeePerGas = txConfig.gasConfig.maxPriorityFeePerGas; + tx.maxFeePerGas = txConfig.gasConfig.maxFeePerGas; + tx.gasLimit = txConfig.gasConfig.gasLimit; } + } - // Sleep for 1 second - await new Promise((resolve) => setTimeout(resolve, 1000)); - tries++; - timedOut = Date.now() >= startedAt.getTime() + timeoutMs; - } while (!timedOut); + if (tx.maxPriorityFeePerGas && !tx.maxFeePerGas) { + tx.maxFeePerGas = await this.estimateMaxFeePerGas( + tx.maxPriorityFeePerGas.toString(), + ); + this.log.info( + `Estimated maxFeePerGas of ${tx.maxFeePerGas} becuase maxPriorityFeePerGas was provided.`, + ); + } - throw new Error(`${fnTag} Timed out ${timeoutMs}ms, polls=${tries}`); + // Fill missing gas fields (do it last) + if (!tx.gasLimit) { + const estimatedGas = await this.web3.eth.estimateGas(tx); + this.log.debug( + `Gas not specified in the transaction values, estimated ${estimatedGas.toString()}`, + ); + tx.gasLimit = estimatedGas; + } + + return tx; } - private async generateBytecode(req: any): Promise { - const tmpContracts = new this.web3.eth.Contract( - (req.contractJSON as any).abi, - ); - const deployment = tmpContracts.deploy({ - data: req.contractJSON.bytecode, - arguments: req.constructorArgs, - }); - const abi = deployment.encodeABI(); - return abi.startsWith("0x") ? abi : `0x${abi}`; + //////////////////////////// + // Contract Deployment + //////////////////////////// + + /** + * Deploy contract to an Ethereum based ledger. + * + * @param req contract and transaction definition + * @returns transaction receipt + */ + public async deployContract( + req: DeployContractV1Request, + ): Promise { + Checks.truthy(req, "deployContract() request arg"); + + if (isWeb3SigningCredentialNone(req.web3SigningCredential)) { + throw new Error(`Cannot deploy contract with pre-signed TX`); + } + + if (isContractJsonDefinition(req.contract)) { + return this.runContractDeployment({ + web3SigningCredential: req.web3SigningCredential, + gasConfig: req.gasConfig, + constructorArgs: req.constructorArgs, + value: req.value, + contractJSON: req.contract.contractJSON, + }); + } else if (isContractKeychainDefinition(req.contract)) { + return this.deployContractFromKeychain(req, req.contract); + } else { + // Exhaustive check + const unknownContract: never = req.contract; + throw new Error( + `Unknown contract definition provided: ${unknownContract}`, + ); + } } - async runDeploy(req: any): Promise { - const web3SigningCredential = req.web3SigningCredential as - | Web3SigningCredentialGethKeychainPassword - | Web3SigningCredentialPrivateKeyHex; + /** + * Internal function for creating and sending contract deployment transaction. + * + * @param config deployment configuration + * @returns transaction receipt + */ + private async runContractDeployment( + config: RunContractDeploymentInput, + ): Promise { + Checks.truthy(config, "runContractDeployment() config arg"); - const bytecode = await this.generateBytecode(req); + const mockContract = new this.web3.eth.Contract(config.contractJSON.abi); + const mockDeployment = mockContract.deploy({ + data: config.contractJSON.bytecode, + arguments: config.constructorArgs as [], + }); + const abi = mockDeployment.encodeABI(); - const receipt = await this.transact({ + return this.transact({ transactionConfig: { - data: bytecode, - from: web3SigningCredential.ethAccount, - gasConfig: req.gasConfig, + data: abi.startsWith("0x") ? abi : `0x${abi}`, + from: config.web3SigningCredential.ethAccount, + gasConfig: config.gasConfig, + value: config.value, }, - web3SigningCredential, + web3SigningCredential: config.web3SigningCredential, }); - - return receipt; } - public async deployContract( - req: DeployContractSolidityBytecodeV1Request, - ): Promise { - const fnTag = `${this.className}#deployContract()`; - Checks.truthy(req, `${fnTag} req`); + /** + * Internal function for deploying contract that has it's JSON stored in a keychain plugin. + * + * @param req contract and transaction definition + * @param contract contract on keychain definition + * @returns transaction receipt + */ + private async deployContractFromKeychain( + req: DeployContractV1Request, + contract: ContractKeychainDefinition, + ): Promise { + Checks.truthy(req, "deployContractFromKeychain() request arg"); + Checks.truthy(req, "deployContractFromKeychain() contract arg"); - if (isWeb3SigningCredentialNone(req.web3SigningCredential)) { - throw new Error(`${fnTag} Cannot deploy contract with pre-signed TX`); - } - if (!req.keychainId || !req.contractName) { - throw new Error( - `${fnTag} Cannot deploy contract without keychainId and the contractName`, - ); - } + // Obtain the contractJSON from keychainPlugin const keychainPlugin = this.pluginRegistry.findOneByKeychainId( - req.keychainId, + contract.keychainId, ); Checks.truthy( keychainPlugin, - `${fnTag} keychain for ID:"${req.keychainId}"`, + `Deployment contract keychain with ID:"${contract.keychainId}"`, ); - if (!keychainPlugin.has(req.contractName)) { + if (!keychainPlugin.has(contract.contractName)) { throw new Error( - `${fnTag} Cannot create an instance of the contract because the contractName sent and the contractName of the JSON doesn't match`, + `Cannot create an instance of the contract because the contractName sent and the contractName of the JSON doesn't match`, ); } - - // obtain the contractJSON from keychainPlugin - const contractStr = await keychainPlugin.get(req.contractName); + const contractStr = await keychainPlugin.get(contract.contractName); const contractJSON = JSON.parse(contractStr); - req.contractJSON = contractJSON; - // deploy the contract - const receipt = await this.runDeploy(req); + const receipt = await this.runContractDeployment({ + web3SigningCredential: req.web3SigningCredential as + | Web3SigningCredentialCactiKeychainRef + | Web3SigningCredentialGethKeychainPassword + | Web3SigningCredentialPrivateKeyHex, + gasConfig: req.gasConfig, + constructorArgs: req.constructorArgs, + value: req.value, + contractJSON, + }); - // save the contract address in the keychainPlugin + // Save the contract address in the keychainPlugin if ( receipt.transactionReceipt.status && receipt.transactionReceipt.contractAddress && receipt.transactionReceipt.contractAddress != null ) { - const networkId = (await this.web3.eth.net.getId()).toString(); + this.log.info( + "Contract deployed successfully, saving address in keychain entry", + ); + const networkId = await this.web3.eth.net.getId(); const address = { address: receipt.transactionReceipt.contractAddress }; - const network = { [networkId]: address }; - contractJSON.networks = network; - keychainPlugin.set(req.contractName, JSON.stringify(contractJSON)); + contractJSON.networks = { [networkId.toString()]: address }; + keychainPlugin.set(contract.contractName, JSON.stringify(contractJSON)); } return receipt; } - public async deployContractJsonObject( - req: DeployContractSolidityBytecodeJsonObjectV1Request, - ): Promise { - const fnTag = `${this.className}#deployContractNoKeychain()`; - if ( - !req.contractJSON || - !req.contractJSON.bytecode || - !req.web3SigningCredential - ) { - throw new Error( - `${fnTag} Cannot deploy contract without contractJSON, bytecode or web3SigningCredential`, - ); - } - return this.runDeploy(req); - } + //////////////////////////// + // Invoke Web3 Methods + //////////////////////////// - // Low level function to call any method from web3.eth - // Should be used only if given functionality is not already covered by another endpoint. + /** + * Low level function to call any method from web3.eth. + * Should be used only if given functionality is not already covered by another endpoint. + * + * @param args web3.eth method and arguments + * @returns method response + */ public async invokeRawWeb3EthMethod( args: InvokeRawWeb3EthMethodV1Request, ): Promise { @@ -864,8 +1018,13 @@ export class PluginLedgerConnectorEthereum return looseWeb3Eth[args.methodName](...web3MethodArgs); } - // Low level function to invoke contract - // Should be used only if given functionality is not already covered by another endpoint. + /** + * Low level function to invoke contract. + * Should be used only if given functionality is not already covered by another endpoint. + * + * @param args web3 contract method and arguments + * @returns method response + */ public async invokeRawWeb3EthContract( args: InvokeRawWeb3EthContractV1Request, ): Promise { @@ -902,61 +1061,4 @@ export class PluginLedgerConnectorEthereum args.invocationParams, ); } - - /** - * Convert connector transaction config to web3js transaction object. - * @param txConfig connector transaction config - * @returns web3js transaction - */ - private async getTransactionFromTxConfig( - txConfig: EthereumTransactionConfig, - ): Promise { - const tx: Transaction = { - from: txConfig.from, - to: txConfig.to, - value: txConfig.value, - nonce: txConfig.nonce, - data: txConfig.data, - }; - - // Apply gas config to the transaction - if (txConfig.gasConfig) { - if (isGasTransactionConfigLegacy(txConfig.gasConfig)) { - if (isGasTransactionConfigEIP1559(txConfig.gasConfig)) { - throw new RuntimeError( - `Detected mixed gasConfig! Use either legacy or EIP-1559 mode. gasConfig - ${JSON.stringify( - txConfig.gasConfig, - )}`, - ); - } - tx.maxPriorityFeePerGas = txConfig.gasConfig.gasPrice; - tx.maxFeePerGas = txConfig.gasConfig.gasPrice; - tx.gasLimit = txConfig.gasConfig.gas; - } else { - tx.maxPriorityFeePerGas = txConfig.gasConfig.maxPriorityFeePerGas; - tx.maxFeePerGas = txConfig.gasConfig.maxFeePerGas; - tx.gasLimit = txConfig.gasConfig.gasLimit; - } - } - - if (tx.maxPriorityFeePerGas && !tx.maxFeePerGas) { - tx.maxFeePerGas = await this.estimateMaxFeePerGas( - tx.maxPriorityFeePerGas.toString(), - ); - this.log.info( - `Estimated maxFeePerGas of ${tx.maxFeePerGas} becuase maxPriorityFeePerGas was provided.`, - ); - } - - // Fill missing gas fields (do it last) - if (!tx.gasLimit) { - const estimatedGas = await this.web3.eth.estimateGas(tx); - this.log.debug( - `Gas not specified in the transaction values, estimated ${estimatedGas.toString()}`, - ); - tx.gasLimit = estimatedGas; - } - - return tx; - } } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/data.fetcher.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/data.fetcher.ts index 88494776493..e20a5161958 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/data.fetcher.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/data.fetcher.ts @@ -1,12 +1,12 @@ import { Transactions } from "./response.type"; -import { totalTxCount, K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "./metrics"; +import { totalTxCount, K_CACTI_ETHEREUM_TOTAL_TX_COUNT } from "./metrics"; export async function collectMetrics( transactions: Transactions, ): Promise { transactions.counter++; totalTxCount - .labels(K_CACTUS_ETHEREUM_TOTAL_TX_COUNT) + .labels(K_CACTI_ETHEREUM_TOTAL_TX_COUNT) .set(transactions.counter); } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/metrics.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/metrics.ts index 0d736b6275c..3696b1b5f71 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/metrics.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/metrics.ts @@ -1,10 +1,10 @@ import { Gauge } from "prom-client"; -export const K_CACTUS_ETHEREUM_TOTAL_TX_COUNT = "cactus_eth_total_tx_count"; +export const K_CACTI_ETHEREUM_TOTAL_TX_COUNT = "cactus_eth_total_tx_count"; export const totalTxCount = new Gauge({ registers: [], - name: K_CACTUS_ETHEREUM_TOTAL_TX_COUNT, + name: K_CACTI_ETHEREUM_TOTAL_TX_COUNT, help: "Total transactions executed", labelNames: ["type"], }); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/prometheus-exporter.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/prometheus-exporter.ts index 312d332d324..6a4b68d9602 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/prometheus-exporter.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/prometheus-exporter/prometheus-exporter.ts @@ -1,7 +1,7 @@ import promClient, { Registry } from "prom-client"; import { Transactions } from "./response.type"; import { collectMetrics } from "./data.fetcher"; -import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "./metrics"; +import { K_CACTI_ETHEREUM_TOTAL_TX_COUNT } from "./metrics"; import { totalTxCount } from "./metrics"; export interface IPrometheusExporterOptions { @@ -27,7 +27,7 @@ export class PrometheusExporter { public async getPrometheusMetrics(): Promise { const result = await this.registry.getSingleMetricAsString( - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT, + K_CACTI_ETHEREUM_TOTAL_TX_COUNT, ); return result; } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/types/model-type-guards.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/types/model-type-guards.ts index fe9f1216a89..d2b24fec0c5 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/types/model-type-guards.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/types/model-type-guards.ts @@ -1,8 +1,11 @@ import { + ContractJsonDefinition, + ContractKeychainDefinition, + DeployedContractJsonDefinition, GasTransactionConfig, GasTransactionConfigEIP1559, GasTransactionConfigLegacy, - Web3SigningCredentialCactusKeychainRef, + Web3SigningCredentialCactiKeychainRef, Web3SigningCredentialGethKeychainPassword, Web3SigningCredentialNone, Web3SigningCredentialPrivateKeyHex, @@ -27,14 +30,14 @@ export function isWeb3SigningCredentialGethKeychainPassword(x?: { return x?.type === Web3SigningCredentialType.GethKeychainPassword; } -export function isWeb3SigningCredentialCactusKeychainRef(x?: { +export function isWeb3SigningCredentialCactiKeychainRef(x?: { type?: Web3SigningCredentialType; keychainEntryKey?: string | unknown; keychainId?: string | unknown; -}): x is Web3SigningCredentialCactusKeychainRef { +}): x is Web3SigningCredentialCactiKeychainRef { return ( !!x?.type && - x?.type === Web3SigningCredentialType.CactusKeychainRef && + x?.type === Web3SigningCredentialType.CactiKeychainRef && !!x?.keychainEntryKey && typeof x?.keychainEntryKey === "string" && x?.keychainEntryKey.trim().length > 0 && @@ -64,3 +67,30 @@ export function isGasTransactionConfigEIP1559( typeof typedGasConfig.maxPriorityFeePerGas !== "undefined" ); } + +export function isContractJsonDefinition( + contract: unknown, +): contract is ContractJsonDefinition { + const typedContract = contract as ContractJsonDefinition; + return typeof typedContract.contractJSON !== "undefined"; +} + +export function isDeployedContractJsonDefinition( + contract: unknown, +): contract is DeployedContractJsonDefinition { + const typedContract = contract as DeployedContractJsonDefinition; + return ( + typeof typedContract.contractJSON !== "undefined" && + typeof typedContract.contractAddress !== "undefined" + ); +} + +export function isContractKeychainDefinition( + contract: unknown, +): contract is ContractKeychainDefinition { + const typedContract = contract as ContractKeychainDefinition; + return ( + typeof typedContract.contractName !== "undefined" && + typeof typedContract.keychainId !== "undefined" + ); +} diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-solidity-bytecode-endpoint-json-object.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-solidity-bytecode-endpoint-json-object.ts deleted file mode 100644 index 8c0c20bbc1f..00000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-solidity-bytecode-endpoint-json-object.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Express, Request, Response } from "express"; - -import { - IWebServiceEndpoint, - IExpressRequestHandler, - IEndpointAuthzOptions, -} from "@hyperledger/cactus-core-api"; - -import { - Logger, - Checks, - LogLevelDesc, - LoggerProvider, - IAsyncProvider, -} from "@hyperledger/cactus-common"; - -import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; - -import { PluginLedgerConnectorEthereum } from "../plugin-ledger-connector-ethereum"; -import { DeployContractSolidityBytecodeJsonObjectV1Request } from "../generated/openapi/typescript-axios"; -import OAS from "../../json/openapi.json"; - -export interface IDeployContractSolidityBytecodeOptionsJsonObject { - logLevel?: LogLevelDesc; - connector: PluginLedgerConnectorEthereum; -} - -export class DeployContractSolidityBytecodeJsonObjectEndpoint - implements IWebServiceEndpoint -{ - public static readonly CLASS_NAME = - "DeployContractSolidityBytecodeEndpointJsonObject"; - - private readonly log: Logger; - - public get className(): string { - return DeployContractSolidityBytecodeJsonObjectEndpoint.CLASS_NAME; - } - - constructor( - public readonly options: IDeployContractSolidityBytecodeOptionsJsonObject, - ) { - const fnTag = `${this.className}#constructor()`; - Checks.truthy(options, `${fnTag} arg options`); - Checks.truthy(options.connector, `${fnTag} arg options.connector`); - - const level = this.options.logLevel || "INFO"; - const label = this.className; - this.log = LoggerProvider.getOrCreate({ level, label }); - } - - public getOasPath() { - return OAS.paths[ - "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode-json-object" - ]; - } - - public getPath(): string { - const apiPath = this.getOasPath(); - return apiPath.post["x-hyperledger-cactus"].http.path; - } - - public getVerbLowerCase(): string { - const apiPath = this.getOasPath(); - return apiPath.post["x-hyperledger-cactus"].http.verbLowerCase; - } - - public getOperationId(): string { - return this.getOasPath().post.operationId; - } - - getAuthorizationOptionsProvider(): IAsyncProvider { - // TODO: make this an injectable dependency in the constructor - return { - get: async () => ({ - isProtected: true, - requiredRoles: [], - }), - }; - } - - public async registerExpress( - expressApp: Express, - ): Promise { - await registerWebServiceEndpoint(expressApp, this); - return this; - } - - public getExpressRequestHandler(): IExpressRequestHandler { - return this.handleRequest.bind(this); - } - - public async handleRequest(req: Request, res: Response): Promise { - const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`; - this.log.debug(reqTag); - const reqBody: DeployContractSolidityBytecodeJsonObjectV1Request = req.body; - try { - const resBody = await this.options.connector.deployContractJsonObject( - reqBody, - ); - res.json(resBody); - } catch (ex) { - this.log.error(`Crash while serving ${reqTag}`, ex); - res.status(500).json({ - message: "Internal Server Error", - error: ex?.stack || ex?.message, - }); - } - } -} diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-solidity-bytecode-endpoint.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-v1-endpoint.ts similarity index 76% rename from packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-solidity-bytecode-endpoint.ts rename to packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-v1-endpoint.ts index f06c9a55967..af2cd074b57 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-solidity-bytecode-endpoint.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/deploy-contract-v1-endpoint.ts @@ -12,12 +12,12 @@ import { LogLevelDesc, LoggerProvider, IAsyncProvider, + safeStringifyException, } from "@hyperledger/cactus-common"; import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; import { PluginLedgerConnectorEthereum } from "../plugin-ledger-connector-ethereum"; -import { DeployContractSolidityBytecodeV1Request } from "../generated/openapi/typescript-axios"; import OAS from "../../json/openapi.json"; export interface IDeployContractSolidityBytecodeOptions { @@ -25,15 +25,13 @@ export interface IDeployContractSolidityBytecodeOptions { connector: PluginLedgerConnectorEthereum; } -export class DeployContractSolidityBytecodeEndpoint - implements IWebServiceEndpoint -{ - public static readonly CLASS_NAME = "DeployContractSolidityBytecodeEndpoint"; +export class DeployContractEndpoint implements IWebServiceEndpoint { + public static readonly CLASS_NAME = "DeployContractEndpoint"; private readonly log: Logger; public get className(): string { - return DeployContractSolidityBytecodeEndpoint.CLASS_NAME; + return DeployContractEndpoint.CLASS_NAME; } constructor(public readonly options: IDeployContractSolidityBytecodeOptions) { @@ -46,18 +44,18 @@ export class DeployContractSolidityBytecodeEndpoint this.log = LoggerProvider.getOrCreate({ level, label }); } - public get oasPath(): (typeof OAS.paths)["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode"] { + public get oasPath(): (typeof OAS.paths)["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract"] { return OAS.paths[ - "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract-solidity-bytecode" + "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/deploy-contract" ]; } public getPath(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.path; + return this.oasPath.post["x-hyperledger-cacti"].http.path; } public getVerbLowerCase(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.verbLowerCase; + return this.oasPath.post["x-hyperledger-cacti"].http.verbLowerCase; } public getOperationId(): string { @@ -88,15 +86,15 @@ export class DeployContractSolidityBytecodeEndpoint public async handleRequest(req: Request, res: Response): Promise { const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`; this.log.debug(reqTag); - const reqBody: DeployContractSolidityBytecodeV1Request = req.body; try { - const resBody = await this.options.connector.deployContract(reqBody); - res.json(resBody); + res + .status(200) + .json(await this.options.connector.deployContract(req.body)); } catch (ex) { this.log.error(`Crash while serving ${reqTag}`, ex); res.status(500).json({ message: "Internal Server Error", - error: ex?.stack || ex?.message, + error: safeStringifyException(ex), }); } } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/get-prometheus-exporter-metrics-endpoint-v1.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/get-prometheus-exporter-metrics-v1-endpoint.ts similarity index 87% rename from packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/get-prometheus-exporter-metrics-endpoint-v1.ts rename to packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/get-prometheus-exporter-metrics-v1-endpoint.ts index 432a100f131..34135a99e6d 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/get-prometheus-exporter-metrics-endpoint-v1.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/get-prometheus-exporter-metrics-v1-endpoint.ts @@ -16,6 +16,7 @@ import { LoggerProvider, Checks, IAsyncProvider, + safeStringifyException, } from "@hyperledger/cactus-common"; import { PluginLedgerConnectorEthereum } from "../plugin-ledger-connector-ethereum"; @@ -54,11 +55,11 @@ export class GetPrometheusExporterMetricsEndpointV1 } public getPath(): string { - return this.oasPath.get["x-hyperledger-cactus"].http.path; + return this.oasPath.get["x-hyperledger-cacti"].http.path; } public getVerbLowerCase(): string { - return this.oasPath.get["x-hyperledger-cactus"].http.verbLowerCase; + return this.oasPath.get["x-hyperledger-cacti"].http.verbLowerCase; } public getOperationId(): string { @@ -88,15 +89,14 @@ export class GetPrometheusExporterMetricsEndpointV1 this.log.debug(`${verbUpper} ${this.getPath()}`); try { - const resBody = - await this.options.connector.getPrometheusExporterMetrics(); - res.status(200); - res.send(resBody); + res + .status(200) + .send(await this.options.connector.getPrometheusExporterMetrics()); } catch (ex) { - this.log.error(`${fnTag} failed to serve request`, ex); + this.log.error(`Crash while serving ${fnTag}`, ex); res.status(500); res.statusMessage = ex.message; - res.json({ error: ex.stack }); + res.json({ error: safeStringifyException(ex) }); } } } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-endpoint-json-object.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-endpoint-json-object.ts deleted file mode 100644 index c7beb955bbb..00000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-endpoint-json-object.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Express, Request, Response } from "express"; - -import { - Logger, - Checks, - LogLevelDesc, - LoggerProvider, - IAsyncProvider, -} from "@hyperledger/cactus-common"; -import { - IEndpointAuthzOptions, - IExpressRequestHandler, - IWebServiceEndpoint, -} from "@hyperledger/cactus-core-api"; -import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; - -import { PluginLedgerConnectorEthereum } from "../plugin-ledger-connector-ethereum"; - -import OAS from "../../json/openapi.json"; - -export interface IInvokeContractEndpointJsonObjectOptions { - logLevel?: LogLevelDesc; - connector: PluginLedgerConnectorEthereum; -} - -export class InvokeContractJsonObjectEndpoint implements IWebServiceEndpoint { - public static readonly CLASS_NAME = "InvokeContractJsonObjectEndpoint"; - - private readonly log: Logger; - - public get className(): string { - return InvokeContractJsonObjectEndpoint.CLASS_NAME; - } - - constructor( - public readonly options: IInvokeContractEndpointJsonObjectOptions, - ) { - const fnTag = `${this.className}#constructor()`; - Checks.truthy(options, `${fnTag} arg options`); - Checks.truthy(options.connector, `${fnTag} arg options.connector`); - - const level = this.options.logLevel || "INFO"; - const label = this.className; - this.log = LoggerProvider.getOrCreate({ level, label }); - } - - public getOasPath() { - return OAS.paths[ - "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/invoke-contract-json-object" - ]; - } - - public getPath(): string { - const apiPath = this.getOasPath(); - return apiPath.post["x-hyperledger-cactus"].http.path; - } - - public getVerbLowerCase(): string { - const apiPath = this.getOasPath(); - return apiPath.post["x-hyperledger-cactus"].http.verbLowerCase; - } - - public getOperationId(): string { - return this.getOasPath().post.operationId; - } - - getAuthorizationOptionsProvider(): IAsyncProvider { - // TODO: make this an injectable dependency in the constructor - return { - get: async () => ({ - isProtected: true, - requiredRoles: [], - }), - }; - } - - public async registerExpress( - expressApp: Express, - ): Promise { - await registerWebServiceEndpoint(expressApp, this); - return this; - } - - public getExpressRequestHandler(): IExpressRequestHandler { - return this.handleRequest.bind(this); - } - - public async handleRequest(req: Request, res: Response): Promise { - const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`; - this.log.debug(reqTag); - const reqBody = req.body; - try { - const resBody = await this.options.connector.getContractInfo(reqBody); - res.json(resBody); - } catch (ex) { - this.log.error(`Crash while serving ${reqTag}`, ex); - res.status(500).json({ - message: "Internal Server Error", - error: ex?.stack || ex?.message, - }); - } - } -} diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-endpoint.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-v1-endpoint.ts similarity index 85% rename from packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-endpoint.ts rename to packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-v1-endpoint.ts index f64943b4e0b..5ffc284515f 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-endpoint.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-contract-v1-endpoint.ts @@ -6,6 +6,7 @@ import { LogLevelDesc, LoggerProvider, IAsyncProvider, + safeStringifyException, } from "@hyperledger/cactus-common"; import { IEndpointAuthzOptions, @@ -17,7 +18,6 @@ import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; import { PluginLedgerConnectorEthereum } from "../plugin-ledger-connector-ethereum"; import OAS from "../../json/openapi.json"; -import { InvokeContractV1Request } from "../generated/openapi/typescript-axios/api"; export interface IInvokeContractEndpointOptions { logLevel?: LogLevelDesc; @@ -50,11 +50,11 @@ export class InvokeContractEndpoint implements IWebServiceEndpoint { } public getPath(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.path; + return this.oasPath.post["x-hyperledger-cacti"].http.path; } public getVerbLowerCase(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.verbLowerCase; + return this.oasPath.post["x-hyperledger-cacti"].http.verbLowerCase; } public getOperationId(): string { @@ -85,17 +85,13 @@ export class InvokeContractEndpoint implements IWebServiceEndpoint { public async handleRequest(req: Request, res: Response): Promise { const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`; this.log.debug(reqTag); - const reqBody: InvokeContractV1Request = req.body; try { - const resBody = await this.options.connector.getContractInfoKeychain( - reqBody, - ); - res.json(resBody); + res.json(await this.options.connector.invokeContract(req.body)); } catch (ex) { this.log.error(`Crash while serving ${reqTag}`, ex); res.status(500).json({ message: "Internal Server Error", - error: ex?.stack || ex?.message, + error: safeStringifyException(ex), }); } } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-raw-web3eth-contract-v1-endpoint.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-raw-web3eth-contract-v1-endpoint.ts index d262b0c0a55..e4fdf66b28e 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-raw-web3eth-contract-v1-endpoint.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-raw-web3eth-contract-v1-endpoint.ts @@ -5,6 +5,7 @@ import { LogLevelDesc, LoggerProvider, IAsyncProvider, + safeStringifyException, } from "@hyperledger/cactus-common"; import { IEndpointAuthzOptions, @@ -14,7 +15,6 @@ import { import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; import { PluginLedgerConnectorEthereum } from "../plugin-ledger-connector-ethereum"; import OAS from "../../json/openapi.json"; -import sanitizeHtml from "sanitize-html"; import { InvokeRawWeb3EthContractV1Response } from "../generated/openapi/typescript-axios"; export interface IInvokeRawWeb3EthContractEndpointOptions { @@ -50,11 +50,11 @@ export class InvokeRawWeb3EthContractEndpoint implements IWebServiceEndpoint { } public getPath(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.path; + return this.oasPath.post["x-hyperledger-cacti"].http.path; } public getVerbLowerCase(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.verbLowerCase; + return this.oasPath.post["x-hyperledger-cacti"].http.verbLowerCase; } public getOperationId(): string { @@ -94,14 +94,11 @@ export class InvokeRawWeb3EthContractEndpoint implements IWebServiceEndpoint { data: methodResponse, }; res.json(response); - } catch (ex: any) { - this.log.warn(`Error while serving ${reqTag}`, ex); - res.json({ - status: 504, - errorDetail: sanitizeHtml(ex, { - allowedTags: [], - allowedAttributes: {}, - }), + } catch (ex) { + this.log.error(`Crash while serving ${reqTag}`, ex); + res.status(500).json({ + message: "Internal Server Error", + error: safeStringifyException(ex), }); } } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-raw-web3eth-method-v1-endpoint.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-raw-web3eth-method-v1-endpoint.ts index 32a8a4f62ee..6d9a144dd7f 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-raw-web3eth-method-v1-endpoint.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/invoke-raw-web3eth-method-v1-endpoint.ts @@ -5,6 +5,7 @@ import { LogLevelDesc, LoggerProvider, IAsyncProvider, + safeStringifyException, } from "@hyperledger/cactus-common"; import { IEndpointAuthzOptions, @@ -14,7 +15,6 @@ import { import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; import { PluginLedgerConnectorEthereum } from "../plugin-ledger-connector-ethereum"; import OAS from "../../json/openapi.json"; -import sanitizeHtml from "sanitize-html"; import { InvokeRawWeb3EthMethodV1Response } from "../public-api"; export interface IInvokeRawWeb3EthMethodEndpointOptions { @@ -48,11 +48,11 @@ export class InvokeRawWeb3EthMethodEndpoint implements IWebServiceEndpoint { } public getPath(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.path; + return this.oasPath.post["x-hyperledger-cacti"].http.path; } public getVerbLowerCase(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.verbLowerCase; + return this.oasPath.post["x-hyperledger-cacti"].http.verbLowerCase; } public getOperationId(): string { @@ -92,14 +92,11 @@ export class InvokeRawWeb3EthMethodEndpoint implements IWebServiceEndpoint { data: methodResponse, }; res.json(response); - } catch (ex: any) { - this.log.warn(`Error while serving ${reqTag}`, ex); - res.json({ - status: 504, - errorDetail: sanitizeHtml(ex, { - allowedTags: [], - allowedAttributes: {}, - }), + } catch (ex) { + this.log.error(`Crash while serving ${reqTag}`, ex); + res.status(500).json({ + message: "Internal Server Error", + error: safeStringifyException(ex), }); } } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/run-transaction-endpoint.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/run-transaction-v1-endpoint.ts similarity index 86% rename from packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/run-transaction-endpoint.ts rename to packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/run-transaction-v1-endpoint.ts index c6b946491ef..a5b461f4def 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/run-transaction-endpoint.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/run-transaction-v1-endpoint.ts @@ -6,6 +6,7 @@ import { LogLevelDesc, LoggerProvider, IAsyncProvider, + safeStringifyException, } from "@hyperledger/cactus-common"; import { IEndpointAuthzOptions, @@ -17,7 +18,6 @@ import { registerWebServiceEndpoint } from "@hyperledger/cactus-core"; import { PluginLedgerConnectorEthereum } from "../plugin-ledger-connector-ethereum"; import OAS from "../../json/openapi.json"; -import { RunTransactionRequest } from "../generated/openapi/typescript-axios/api"; export interface IRunTransactionEndpointOptions { logLevel?: LogLevelDesc; @@ -50,11 +50,11 @@ export class RunTransactionEndpoint implements IWebServiceEndpoint { } public getPath(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.path; + return this.oasPath.post["x-hyperledger-cacti"].http.path; } public getVerbLowerCase(): string { - return this.oasPath.post["x-hyperledger-cactus"].http.verbLowerCase; + return this.oasPath.post["x-hyperledger-cacti"].http.verbLowerCase; } public getOperationId(): string { @@ -85,15 +85,13 @@ export class RunTransactionEndpoint implements IWebServiceEndpoint { public async handleRequest(req: Request, res: Response): Promise { const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`; this.log.debug(reqTag); - const reqBody: RunTransactionRequest = req.body; try { - const resBody = await this.options.connector.transact(reqBody); - res.json(resBody); + res.json(await this.options.connector.transact(req.body)); } catch (ex) { this.log.error(`Crash while serving ${reqTag}`, ex); res.status(500).json({ message: "Internal Server Error", - error: ex?.stack || ex?.message, + error: safeStringifyException(ex), }); } } diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/watch-blocks-v1-endpoint.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/watch-blocks-v1-endpoint.ts index 027ce9b0f6d..4a82275af4a 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/watch-blocks-v1-endpoint.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/main/typescript/web-services/watch-blocks-v1-endpoint.ts @@ -7,6 +7,7 @@ import { LogLevelDesc, LoggerProvider, Checks, + safeStringifyException, } from "@hyperledger/cactus-common"; import { WatchBlocksV1Options, @@ -108,7 +109,14 @@ export class WatchBlocksV1Endpoint { newBlocksSubscription.on("error", async (error) => { console.log("Error when subscribing to New block header: ", error); - socket.emit(WatchBlocksV1.Error, error.message); + socket.emit(WatchBlocksV1.Error, safeStringifyException(error)); + newBlocksSubscription.unsubscribe(); + }); + + log.debug("Subscribing to Web3 new block headers event..."); + + socket.on("disconnect", async (reason: string) => { + log.debug("WebSocket:disconnect reason=%o", reason); await newBlocksSubscription.unsubscribe(); }); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-json-object-v1.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-json-object-v1.test.ts index 9fdc292e936..c396b603a97 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-json-object-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-json-object-v1.test.ts @@ -41,8 +41,9 @@ import { PluginLedgerConnectorEthereum, Web3SigningCredentialType, DefaultApi as EthereumApi, - DeployContractSolidityBytecodeJsonObjectV1Request, - InvokeContractJsonObjectV1Request, + ContractJsonDefinition, + DeployContractV1Request, + InvokeContractV1Request, } from "../../../main/typescript/public-api"; const containerImageName = "ghcr.io/hyperledger/cacti-geth-all-in-one"; @@ -167,13 +168,15 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { ////////////////////////////////// test("deploys contract using json object", async () => { - const deployOut = await apiClient.deployContractSolBytecodeJsonObjectV1({ + const deployOut = await apiClient.deployContract({ + contract: { + contractJSON: HelloWorldContractJson, + }, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - contractJSON: HelloWorldContractJson, }); expect(deployOut).toBeTruthy(); expect(deployOut.data).toBeTruthy(); @@ -185,8 +188,11 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { expect(typeof contractAddress).toBe("string"); expect(contractAddress).toBeTruthy(); - const invokeOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, + const invokeOut = await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Call, methodName: "sayHello", params: [], @@ -195,7 +201,6 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - contractJSON: HelloWorldContractJson, }); expect(invokeOut).toBeTruthy(); expect(invokeOut.data).toBeTruthy(); @@ -204,14 +209,16 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { }); test("deploys contract using json object with constructorArgs", async () => { - const deployOut = await apiClient.deployContractSolBytecodeJsonObjectV1({ + const deployOut = await apiClient.deployContract({ + contract: { + contractJSON: HelloWorldWithArgContractJson, + }, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, constructorArgs: ["Johnny"], - contractJSON: HelloWorldWithArgContractJson, }); expect(deployOut).toBeTruthy(); expect(deployOut.data).toBeTruthy(); @@ -219,40 +226,39 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { expect(deployOut.data.transactionReceipt.contractAddress).toBeTruthy(); }); - test("deployContractSolBytecodeJsonObjectV1 without contractJSON should fail", async () => { + test("deployContract without contractJSON should fail", async () => { try { - await apiClient.deployContractSolBytecodeJsonObjectV1({ + await apiClient.deployContract({ + contract: {} as ContractJsonDefinition, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - } as DeployContractSolidityBytecodeJsonObjectV1Request); - fail( - "Expected deployContractSolBytecodeJsonObjectV1 call to fail but it succeeded.", - ); + }); + fail("Expected deployContract call to fail but it succeeded."); } catch (error) { - console.log("deployContractSolBytecodeJsonObjectV1 failed as expected"); + console.log("deployContract failed as expected"); } }); - test("deployContractSolBytecodeJsonObjectV1 with additional parameters should fail", async () => { + test("deployContract with additional parameters should fail", async () => { try { - await apiClient.deployContractSolBytecodeJsonObjectV1({ + await apiClient.deployContract({ + contract: { + contractJSON: HelloWorldContractJson, + }, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, gas: 1000000, - contractJSON: HelloWorldContractJson, fake: 4, - } as DeployContractSolidityBytecodeJsonObjectV1Request); - fail( - "Expected deployContractSolBytecodeJsonObjectV1 call to fail but it succeeded.", - ); + } as DeployContractV1Request); + fail("Expected deployContract call to fail but it succeeded."); } catch (error) { - console.log("deployContractSolBytecodeJsonObjectV1 failed as expected"); + console.log("deployContract failed as expected"); } }); @@ -261,48 +267,51 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { ////////////////////////////////// test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async () => { - const nonce = await web3.eth.getTransactionCount(WHALE_ACCOUNT_ADDRESS); const newName = `DrCactus${uuidV4()}`; - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractJSON: HelloWorldContractJson, + const setNameOut = await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Send, methodName: "setName", - contractAddress, params: [newName], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - nonce: nonce.toString(), }); expect(setNameOut).toBeTruthy(); expect(setNameOut.data).toBeTruthy(); try { - await apiClient.invokeContractV1NoKeychain({ - contractJSON: HelloWorldContractJson, + await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Send, - methodName: "setName", - contractAddress, + methodName: "foo", params: [newName], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - nonce: nonce.toString(), }); fail("Expected getContractInfoKeychain call to fail but it succeeded."); } catch (error) { - expect(error).not.toEqual("Nonce too low"); + expect(error).toBeTruthy(); } - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractJSON: HelloWorldContractJson, + const getNameOut = await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Send, methodName: "getName", - contractAddress, params: [], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, @@ -314,11 +323,13 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { expect(getNameOut.data).toBeTruthy(); expect(getNameOut.data.success).toBeTruthy(); - const invokeGetNameOut = await apiClient.invokeContractV1NoKeychain({ - contractJSON: HelloWorldContractJson, + const invokeGetNameOut = await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Call, methodName: "getName", - contractAddress, params: [], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, @@ -334,13 +345,14 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { test("invoke Web3SigningCredentialType.PrivateKeyHex", async () => { const priorityFee = web3.utils.toWei(2, "gwei"); - const nonce = await web3.eth.getTransactionCount(testEthAccount.address); const newName = `DrCactus${uuidV4()}`; - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractJSON: HelloWorldContractJson, + const setNameOut = await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Send, methodName: "setName", - contractAddress, params: [newName], gasConfig: { maxPriorityFeePerGas: priorityFee, @@ -350,17 +362,18 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { secret: testEthAccount.privateKey, type: Web3SigningCredentialType.PrivateKeyHex, }, - nonce: nonce.toString(), }); expect(setNameOut).toBeTruthy(); expect(setNameOut.data).toBeTruthy(); try { - await apiClient.invokeContractV1NoKeychain({ - contractJSON: HelloWorldContractJson, + await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Send, - methodName: "setName", - contractAddress, + methodName: "foo", params: [newName], gasConfig: { maxPriorityFeePerGas: priorityFee, @@ -370,18 +383,19 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { secret: testEthAccount.privateKey, type: Web3SigningCredentialType.PrivateKeyHex, }, - nonce: nonce.toString(), }); fail("Expected getContractInfoKeychain call to fail but it succeeded."); } catch (error) { - expect(error).not.toEqual("Nonce too low"); + expect(error).toBeTruthy(); } - const invokeGetNameOut = await apiClient.invokeContractV1NoKeychain({ - contractJSON: HelloWorldContractJson, + const invokeGetNameOut = await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Call, methodName: "getName", - contractAddress, params: [], web3SigningCredential: { ethAccount: testEthAccount.address, @@ -395,19 +409,21 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { expect(invokeGetNameOut.data.callOutput).toBe(newName); }); - test("invokeContractV1NoKeychain without methodName should fail", async () => { + test("invokeContractV1 without methodName should fail", async () => { try { - await apiClient.invokeContractV1NoKeychain({ - contractJSON: HelloWorldContractJson, + await apiClient.invokeContractV1({ + contract: { + contractJSON: HelloWorldContractJson, + contractAddress, + }, invocationType: EthContractInvocationType.Send, - contractAddress, params: [`DrCactus${uuidV4()}`], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - } as InvokeContractJsonObjectV1Request); + } as InvokeContractV1Request); fail( "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", ); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-keychain-v1.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-keychain-v1.test.ts index 6fba7f0bdc2..a0342a05d16 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-keychain-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-keychain-v1.test.ts @@ -39,14 +39,15 @@ import HelloWorldWithArgContractJson from "../../solidity/hello-world-with-arg-c import { EthContractInvocationType, PluginLedgerConnectorEthereum, - Web3SigningCredentialCactusKeychainRef, + Web3SigningCredentialCactiKeychainRef, Web3SigningCredentialType, DefaultApi as EthereumApi, - DeployContractSolidityBytecodeV1Request, RunTransactionRequest, InvokeContractV1Request, + DeployContractV1Request, + ContractKeychainDefinition, } from "../../../main/typescript/public-api"; -import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "../../../main/typescript/prometheus-exporter/metrics"; +import { K_CACTI_ETHEREUM_TOTAL_TX_COUNT } from "../../../main/typescript/prometheus-exporter/metrics"; const containerImageName = "ghcr.io/hyperledger/cacti-geth-all-in-one"; const containerImageVersion = "2023-07-27-2a8c48ed6"; @@ -169,9 +170,11 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { ////////////////////////////////// test("deploys contract using keychain", async () => { - const deployOut = await apiClient.deployContractSolBytecodeV1({ - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), + const deployOut = await apiClient.deployContract({ + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", @@ -187,10 +190,12 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { .contractAddress as string; expect(typeof contractAddress).toBe("string"); const invokeOut = await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Call, methodName: "sayHello", - keychainId: keychainPlugin.getKeychainId(), params: [], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, @@ -205,9 +210,11 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { }); test("deploys contract using keychain with constructorArgs", async () => { - const deployOut = await apiClient.deployContractSolBytecodeV1({ - contractName: HelloWorldWithArgContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), + const deployOut = await apiClient.deployContract({ + contract: { + contractName: HelloWorldWithArgContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", @@ -221,29 +228,31 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { expect(deployOut.data.transactionReceipt.contractAddress).toBeTruthy(); }); - test("deployContractSolBytecodeV1 without contractName should fail", async () => { + test("deployContract without contractName should fail", async () => { try { - await apiClient.deployContractSolBytecodeV1({ - keychainId: keychainPlugin.getKeychainId(), + await apiClient.deployContract({ + contract: { + keychainId: keychainPlugin.getKeychainId(), + } as ContractKeychainDefinition, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - } as DeployContractSolidityBytecodeV1Request); - fail( - "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", - ); + }); + fail("Expected deployContract call to fail but it succeeded."); } catch (error) { - console.log("deployContractSolBytecodeV1 failed as expected"); + console.log("deployContract failed as expected"); } }); - test("deployContractSolBytecodeV1 with additional parameters should fail", async () => { + test("deployContract with additional parameters should fail", async () => { try { - await apiClient.deployContractSolBytecodeV1({ - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), + await apiClient.deployContract({ + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", @@ -251,12 +260,10 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { }, gas: 1000000, fake: 4, - } as DeployContractSolidityBytecodeV1Request); - fail( - "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", - ); + } as DeployContractV1Request); + fail("Expected deployContract call to fail but it succeeded."); } catch (error) { - console.log("deployContractSolBytecodeV1 failed as expected"); + console.log("deployContract failed as expected"); } }); @@ -265,48 +272,51 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { ////////////////////////////////// test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async () => { - const nonce = await web3.eth.getTransactionCount(WHALE_ACCOUNT_ADDRESS); const newName = `DrCactus${uuidV4()}`; const setNameOut = await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Send, methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), params: [newName], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - nonce: nonce.toString(), }); expect(setNameOut).toBeTruthy(); expect(setNameOut.data).toBeTruthy(); try { await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), + methodName: "foo", params: [newName], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - nonce: nonce.toString(), }); fail("Expected invokeContractV1 call to fail but it succeeded."); } catch (error) { - expect(error).not.toEqual("Nonce too low"); + expect(error).toBeTruthy(); } const getNameOut = await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Send, methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), params: [], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, @@ -319,10 +329,12 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { expect(getNameOut.data.success).toBeTruthy(); const invokeGetNameOut = await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Call, methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), params: [], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, @@ -373,23 +385,22 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { type: Web3SigningCredentialType.None, }, } as RunTransactionRequest); - fail( - "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", - ); + fail("Expected runTransactionV1 call to fail but it succeeded."); } catch (error) { - console.log("deployContractSolBytecodeV1 failed as expected"); + console.log("runTransactionV1 failed as expected"); } }); test("invoke Web3SigningCredentialType.PrivateKeyHex", async () => { const priorityFee = web3.utils.toWei(2, "gwei"); - const nonce = await web3.eth.getTransactionCount(testEthAccount.address); const newName = `DrCactus${uuidV4()}`; const setNameOut = await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Send, methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), params: [newName], gasConfig: { maxPriorityFeePerGas: priorityFee, @@ -399,17 +410,18 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { secret: testEthAccount.privateKey, type: Web3SigningCredentialType.PrivateKeyHex, }, - nonce: nonce.toString(), }); expect(setNameOut).toBeTruthy(); expect(setNameOut.data).toBeTruthy(); try { await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), + methodName: "foo", params: [newName], gasConfig: { maxPriorityFeePerGas: priorityFee, @@ -419,18 +431,19 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { secret: testEthAccount.privateKey, type: Web3SigningCredentialType.PrivateKeyHex, }, - nonce: nonce.toString(), }); fail("Expected invokeContractV1 call to fail but it succeeded."); } catch (error) { - expect(error).not.toEqual("Nonce too low"); + expect(error).toBeTruthy(); } const invokeGetNameOut = await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Call, methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), params: [], web3SigningCredential: { ethAccount: testEthAccount.address, @@ -444,40 +457,41 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { expect(invokeGetNameOut.data.callOutput).toBe(newName); }); - test("invoke Web3SigningCredentialType.CactusKeychainRef", async () => { + test("invoke Web3SigningCredentialType.CactiKeychainRef", async () => { const newName = `DrCactus${uuidV4()}`; - const nonce = await web3.eth.getTransactionCount(testEthAccount.address); const priorityFee = web3.utils.toWei(2, "gwei"); - const web3SigningCredential: Web3SigningCredentialCactusKeychainRef = { + const web3SigningCredential: Web3SigningCredentialCactiKeychainRef = { ethAccount: testEthAccount.address, keychainEntryKey, keychainId: keychainPlugin.getKeychainId(), - type: Web3SigningCredentialType.CactusKeychainRef, + type: Web3SigningCredentialType.CactiKeychainRef, }; - // @todo - using too large nonce freezes the test! Fix that const setNameOut = await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Send, methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), params: [newName], gasConfig: { maxPriorityFeePerGas: priorityFee, }, web3SigningCredential, - nonce: nonce.toString(), }); expect(setNameOut).toBeTruthy(); expect(setNameOut.data).toBeTruthy(); try { await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), + methodName: "foo", params: [newName], gasConfig: { maxPriorityFeePerGas: priorityFee, @@ -487,18 +501,19 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - nonce: nonce.toString(), }); fail("Expected invokeContractV1 call to fail but it succeeded."); } catch (error) { - expect(error).not.toEqual("Nonce too low"); + expect(error).toBeTruthy(); } const invokeGetNameOut = await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Call, methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), params: [], web3SigningCredential, }); @@ -511,9 +526,11 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { test("invokeContractV1 without methodName should fail", async () => { try { await apiClient.invokeContractV1({ - contractName: HelloWorldContractJson.contractName, + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Send, - keychainId: keychainPlugin.getKeychainId(), params: [`DrCactus${uuidV4()}`], web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, @@ -521,11 +538,9 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { type: Web3SigningCredentialType.GethKeychainPassword, }, } as InvokeContractV1Request); - fail( - "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", - ); + fail("Expected invokeContractV1 call to fail but it succeeded."); } catch (error) { - console.log("deployContractSolBytecodeV1 failed as expected"); + console.log("invokeContractV1 failed as expected"); } }); @@ -534,14 +549,14 @@ describe("Ethereum contract deploy and invoke using keychain tests", () => { const res = await apiClient.getPrometheusMetricsV1(); const promMetricsOutput = "# HELP " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + + K_CACTI_ETHEREUM_TOTAL_TX_COUNT + " Total transactions executed\n" + "# TYPE " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + + K_CACTI_ETHEREUM_TOTAL_TX_COUNT + " gauge\n" + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + + K_CACTI_ETHEREUM_TOTAL_TX_COUNT + '{type="' + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + + K_CACTI_ETHEREUM_TOTAL_TX_COUNT + '"} 3'; expect(res); expect(res.data); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-contract-v1.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-contract-v1.test.ts index da17ab52878..cb5cc2cb9fb 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-contract-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-contract-v1.test.ts @@ -86,8 +86,10 @@ describe("invokeRawWeb3EthContract Tests", () => { log.info("Deploy contract to interact with..."); const deployOut = await connector.deployContract({ - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/manual/geth-alchemy-integration-manual-check.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/manual/geth-alchemy-integration-manual-check.test.ts index 5ced4aeee89..725157745cc 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/manual/geth-alchemy-integration-manual-check.test.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/manual/geth-alchemy-integration-manual-check.test.ts @@ -76,8 +76,10 @@ describe("Alchemy integration manual tests", () => { test("deploy sample contract to testnet", async () => { const deployOut = await connector.deployContract({ - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, web3SigningCredential: { ethAccount: ETH_ADDRESS, secret: ETH_PRIVATE_KEY, @@ -96,11 +98,13 @@ describe("Alchemy integration manual tests", () => { ); expect(typeof contractAddress).toBe("string"); - const invokeOut = await connector.getContractInfoKeychain({ - contractName: HelloWorldContractJson.contractName, + const invokeOut = await connector.invokeContract({ + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, invocationType: EthContractInvocationType.Call, methodName: "sayHello", - keychainId: keychainPlugin.getKeychainId(), params: [], web3SigningCredential: { ethAccount: ETH_ADDRESS, diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/unit/model-type-guards.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/unit/model-type-guards.test.ts index 983bfa69d34..46b04dd374d 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/unit/model-type-guards.test.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/unit/model-type-guards.test.ts @@ -1,5 +1,8 @@ import "jest-extended"; import { + isContractJsonDefinition, + isContractKeychainDefinition, + isDeployedContractJsonDefinition, isGasTransactionConfigEIP1559, isGasTransactionConfigLegacy, isWeb3SigningCredentialGethKeychainPassword, @@ -104,4 +107,77 @@ describe("Type guards for OpenAPI spec model type definitions", () => { ).toBe(false); expect(isGasTransactionConfigEIP1559({})).toBe(false); }); + + test("isContractJsonDefinition()", () => { + expect( + isContractJsonDefinition({ + contractJSON: { + abi: "test", + }, + }), + ).toBe(true); + + expect( + isContractJsonDefinition({ + foo: "1234", + }), + ).toBe(false); + expect(isContractJsonDefinition({})).toBe(false); + }); + + test("isDeployedContractJsonDefinition()", () => { + expect( + isDeployedContractJsonDefinition({ + contractJSON: { + abi: "test", + }, + contractAddress: "asd", + }), + ).toBe(true); + + expect( + isDeployedContractJsonDefinition({ + contractJSON: { + abi: "test", + }, + }), + ).toBe(false); + expect( + isDeployedContractJsonDefinition({ + contractAddress: "asd", + }), + ).toBe(false); + expect( + isDeployedContractJsonDefinition({ + foo: "1234", + }), + ).toBe(false); + expect(isDeployedContractJsonDefinition({})).toBe(false); + }); + + test("isContractKeychainDefinition()", () => { + expect( + isContractKeychainDefinition({ + contractName: "foo", + keychainId: "bar", + }), + ).toBe(true); + + expect( + isContractKeychainDefinition({ + contractName: "foo", + }), + ).toBe(false); + expect( + isContractKeychainDefinition({ + keychainId: "foo", + }), + ).toBe(false); + expect( + isContractKeychainDefinition({ + foo: "bar", + }), + ).toBe(false); + expect(isContractKeychainDefinition({})).toBe(false); + }); }); diff --git a/packages/cactus-test-plugin-ledger-connector-ethereum/src/test/typescript/integration/api-client/verifier-integration-with-ethereum-connector.test.ts b/packages/cactus-test-plugin-ledger-connector-ethereum/src/test/typescript/integration/api-client/verifier-integration-with-ethereum-connector.test.ts index e5248e45c41..1c032dc080b 100644 --- a/packages/cactus-test-plugin-ledger-connector-ethereum/src/test/typescript/integration/api-client/verifier-integration-with-ethereum-connector.test.ts +++ b/packages/cactus-test-plugin-ledger-connector-ethereum/src/test/typescript/integration/api-client/verifier-integration-with-ethereum-connector.test.ts @@ -242,8 +242,10 @@ describe("Verifier integration with ethereum connector tests", () => { // Deploy contract to interact with const deployOut = await connector.deployContract({ - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), + contract: { + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + }, web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", @@ -561,13 +563,14 @@ describe("Verifier integration with ethereum connector tests", () => { const method = { type: "web3Eth", command: "foo" }; const args = {}; - const results = await globalVerifierFactory - .getVerifier(ethereumValidatorId) - .sendSyncRequest(contract, method, args); - - expect(results).toBeTruthy(); - expect(results.status).toEqual(504); - expect(results.errorDetail).toBeTruthy(); + try { + await globalVerifierFactory + .getVerifier(ethereumValidatorId) + .sendSyncRequest(contract, method, args); + fail("Expected sendSyncRequest call to fail but it succeeded."); + } catch (error) { + console.log("sendSyncRequest failed as expected"); + } }); function assertBlockHeader(header?: Web3BlockHeader) { diff --git a/packages/cactus-test-plugin-ledger-connector-ethereum/tsconfig.json b/packages/cactus-test-plugin-ledger-connector-ethereum/tsconfig.json index 15f75ed343a..c7417cefd9d 100644 --- a/packages/cactus-test-plugin-ledger-connector-ethereum/tsconfig.json +++ b/packages/cactus-test-plugin-ledger-connector-ethereum/tsconfig.json @@ -8,10 +8,7 @@ "rootDir": "./src", "tsBuildInfoFile": "../../.build-cache/cactus-test-plugin-ledger-connector-ethereum.tsbuildinfo" }, - "include": [ - "./src", - "src/**/*.json" - ], + "include": ["./src", "src/**/*.json"], "references": [ { "path": "../cactus-cmd-api-server/tsconfig.json" @@ -38,4 +35,4 @@ "path": "../cactus-test-geth-ledger/tsconfig.json" } ] -} \ No newline at end of file +}