diff --git a/.taprc b/.taprc index f292d01ac9..1f42d107c0 100644 --- a/.taprc +++ b/.taprc @@ -21,17 +21,6 @@ files: - ./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v2.3.0-deploy-contract-from-json-json-object.test.ts - ./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/openapi/openapi-validation.test.ts - ./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v21.4.1-invoke-contract-json-object.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-invoke-contract-json-object-endpoints.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v21.4.1-invoke-contract-json-object-endpoints.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v21.4.1-deploy-contract-from-json-json-object-endpoints.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-deploy-contract-from-json-json-object-endpoints.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/openapi/openapi-validation-no-keychain.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-invoke-contract-json-object.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-deploy-contract-from-json.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v21.4.1-deploy-contract-from-json-json-object.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-deploy-contract-from-json-json-object.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/openapi/openapi-validation.test.ts - - ./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v21.4.1-invoke-contract-json-object.test.ts - ./extensions/cactus-plugin-htlc-coordinator-besu/src/test/typescript/integration/plugin-htlc-coordinator/counterparty-htlc-endpoint.test.ts - ./extensions/cactus-plugin-htlc-coordinator-besu/src/test/typescript/integration/plugin-htlc-coordinator/own-htlc-endpoint.test.ts - ./extensions/cactus-plugin-htlc-coordinator-besu/src/test/typescript/integration/plugin-htlc-coordinator/withdraw-counterparty-endpoint.test.ts diff --git a/jest.config.js b/jest.config.js index f78a089ae6..5bd26f3939 100644 --- a/jest.config.js +++ b/jest.config.js @@ -26,17 +26,6 @@ module.exports = { `./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v2.3.0-deploy-contract-from-json-json-object.test.ts`, `./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/openapi/openapi-validation.test.ts`, `./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v21.4.1-invoke-contract-json-object.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-invoke-contract-json-object-endpoints.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v21.4.1-invoke-contract-json-object-endpoints.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v21.4.1-deploy-contract-from-json-json-object-endpoints.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-deploy-contract-from-json-json-object-endpoints.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/openapi/openapi-validation-no-keychain.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-invoke-contract-json-object.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-deploy-contract-from-json.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v21.4.1-deploy-contract-from-json-json-object.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v2.3.0-deploy-contract-from-json-json-object.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/openapi/openapi-validation.test.ts`, - `./packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/v21.4.1-invoke-contract-json-object.test.ts`, `./extensions/cactus-plugin-htlc-coordinator-besu/src/test/typescript/integration/plugin-htlc-coordinator/counterparty-htlc-endpoint.test.ts`, `./extensions/cactus-plugin-htlc-coordinator-besu/src/test/typescript/integration/plugin-htlc-coordinator/own-htlc-endpoint.test.ts`, `./extensions/cactus-plugin-htlc-coordinator-besu/src/test/typescript/integration/plugin-htlc-coordinator/withdraw-counterparty-endpoint.test.ts`, diff --git a/packages/cactus-plugin-ledger-connector-ethereum/package.json b/packages/cactus-plugin-ledger-connector-ethereum/package.json index 5084fbbdc7..919d1514c9 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/package.json +++ b/packages/cactus-plugin-ledger-connector-ethereum/package.json @@ -73,9 +73,9 @@ "rxjs": "7.8.1", "sanitize-html": "2.7.0", "typescript-optional": "2.0.1", - "web3": "4.0.3-dev.602dada.0", - "web3-eth-contract": "4.0.3-dev.602dada.0", - "web3-utils": "4.0.3-dev.602dada.0" + "web3": "4.0.3", + "web3-eth-contract": "4.0.3", + "web3-utils": "4.0.3" }, "devDependencies": { "@hyperledger/cactus-plugin-keychain-memory": "2.0.0-alpha.1", @@ -84,8 +84,8 @@ "@types/minimist": "1.2.2", "@types/sanitize-html": "2.6.2", "chalk": "4.1.2", - "web3-eth": "4.0.3-dev.602dada.0", - "web3-eth-accounts": "4.0.3-dev.602dada.0" + "web3-eth": "4.0.3", + "web3-eth-accounts": "4.0.3" }, "engines": { "node": ">=10", 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 85803ddac0..e9940077c7 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 @@ -187,10 +187,10 @@ export class PluginLedgerConnectorEthereum public async shutdown(): Promise { this.log.info(`Shutting down ${this.className}...`); const provider = this.web3.currentProvider; - if (provider && typeof provider == "object") { - if ("disconnect" in provider) { - provider.disconnect(1000, "shutdown"); - } + try { + provider?.disconnect(1000, "shutdown"); + } catch (error) { + this.log.info("Could not disconnect the provider - may not be supported"); } } @@ -818,10 +818,13 @@ export class PluginLedgerConnectorEthereum ); const looseWeb3Eth = this.web3.eth as any; - const isSafeToCall = this.isSafeToCallObjectMethod( - looseWeb3Eth, - args.methodName, - ); + // web3.eth methods in 4.X are stored in parent class + const isSafeToCall = + this.isSafeToCallObjectMethod(looseWeb3Eth, args.methodName) || + this.isSafeToCallObjectMethod( + Object.getPrototypeOf(looseWeb3Eth), + args.methodName, + ); if (!isSafeToCall) { throw new RuntimeError( `Invalid method name provided in request. ${args.methodName} does not exist on the Web3.Eth object.`, diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/scripts/get-quorum-connector-status.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/scripts/get-ethereum-connector-status.ts similarity index 100% rename from packages/cactus-plugin-ledger-connector-ethereum/src/scripts/get-quorum-connector-status.ts rename to packages/cactus-plugin-ledger-connector-ethereum/src/scripts/get-ethereum-connector-status.ts diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json-json-object-endpoints.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json-json-object-endpoints.test.ts deleted file mode 100644 index 740cad352d..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json-json-object-endpoints.test.ts +++ /dev/null @@ -1,400 +0,0 @@ -import test, { Test } from "tape-promise/tape"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "../../../../../main/typescript/prometheus-exporter/metrics"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, - DefaultApi as EthereumApi, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; - -const testCase = "Ethereum Ledger Connector Plugin"; -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { Server as SocketIoServer } from "socket.io"; - -const logLevel: LogLevelDesc = "INFO"; - -test("BEFORE " + testCase, async (t: Test) => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning didn't throw OK"); - t.end(); -}); - -test(testCase, async (t: Test) => { - const containerImageVersion = "2021-01-08-7a055c3"; // Quorum v2.3.0, Tessera v0.10.0 - - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - await pruneDockerAllIfGithubAction({ logLevel }); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - - // Instantiate connector with the keychain plugin that already has the - // private key we want to use for one of our tests - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - t.comment( - `Metrics URL: ${apiHost}/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics`, - ); - - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new EthereumApi(apiConfig); - - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - await connector.getOrCreateWebServices(); - await connector.registerWebServices(expressApp, wsApi); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - t.ok(balance, "Retrieved balance of test account OK"); - t.equals( - balance.toString(), - initTransferValue, - "Balance of test account is OK", - ); - - let contractAddress: string; - - test("deploys contract via .json file", async (t2: Test) => { - const deployOut = await apiClient.deployContractSolBytecodeJsonObjectV1({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(deployOut, "deployContract() output is truthy OK"); - t2.ok( - deployOut.data.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t2.ok( - deployOut.data.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - - contractAddress = deployOut.data.transactionReceipt - .contractAddress as string; - t2.ok( - typeof contractAddress === "string", - "contractAddress typeof string OK", - ); - - const invokeOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: "1000000", - contractJSON: HelloWorldContractJson, - }); - t2.ok(invokeOut.data.callOutput, "sayHello() output is truthy"); - t2.true( - typeof invokeOut.data.callOutput === "string", - "sayHello() output is type of string", - ); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount( - firstHighNetWorthAccount, - ); - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: "1000000", - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.data.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok( - getNameOut.data.success, - `getName() SEND invocation produced receipt OK`, - ); - - const getNameRes = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameRes.data.callOutput, - newName, - "setName() invocation #2 output is truthy OK", - ); - - t2.end(); - }); - - test("invoke Web3SigningCredentialType.NONE", async (t2: Test) => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - t2.ok(balance2, "Retrieved balance of test account 2 OK"); - t2.equals( - balance2.toString(), - value.toString(), - "Balance of test account2 is OK", - ); - t2.end(); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: "1000000", - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.data.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - // const { callOutput: getNameOut } = - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - // gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut.data.callOutput, - newName, - `getName() output reflects the update OK`, - ); - - const getNameOut2 = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - //gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut2, "getName() invocation #2 output is truthy OK"); - - t2.end(); - }); - - test("get prometheus exporter metrics", async (t2: Test) => { - const res = await apiClient.getPrometheusMetricsV1(); - const promMetricsOutput = - "# HELP " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " Total transactions executed\n" + - "# TYPE " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " gauge\n" + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '{type="' + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '"} 3'; - t2.ok(res); - t2.ok(res.data); - t2.equal(res.status, 200); - t2.true( - res.data.includes(promMetricsOutput), - "Total Transaction Count of 3 recorded as expected. RESULT OK.", - ); - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json-json-object.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json-json-object.test.ts deleted file mode 100644 index 80e9422b29..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json-json-object.test.ts +++ /dev/null @@ -1,391 +0,0 @@ -import test, { Test } from "tape-promise/tape"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "../../../../../main/typescript/prometheus-exporter/metrics"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, - DefaultApi as EthereumApi, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; - -const testCase = "Ethereum Ledger Connector Plugin"; -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { Server as SocketIoServer } from "socket.io"; - -const logLevel: LogLevelDesc = "INFO"; - -test("BEFORE " + testCase, async (t: Test) => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning didn't throw OK"); - t.end(); -}); - -test(testCase, async (t: Test) => { - const containerImageVersion = "2021-01-08-7a055c3"; // Quorum v2.3.0, Tessera v0.10.0 - - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - await pruneDockerAllIfGithubAction({ logLevel }); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - - // Instantiate connector with the keychain plugin that already has the - // private key we want to use for one of our tests - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - t.comment( - `Metrics URL: ${apiHost}/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics`, - ); - - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new EthereumApi(apiConfig); - - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - await connector.getOrCreateWebServices(); - await connector.registerWebServices(expressApp, wsApi); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - t.ok(balance, "Retrieved balance of test account OK"); - t.equals( - balance.toString(), - initTransferValue, - "Balance of test account is OK", - ); - - let contractAddress: string; - - test("deploys contract via .json file", async (t2: Test) => { - const deployOut = await connector.deployContractJsonObject({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(deployOut, "deployContract() output is truthy OK"); - t2.ok( - deployOut.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t2.ok( - deployOut.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - - contractAddress = deployOut.transactionReceipt.contractAddress as string; - t2.ok( - typeof contractAddress === "string", - "contractAddress typeof string OK", - ); - - const { callOutput: helloMsg } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(helloMsg, "sayHello() output is truthy"); - t2.true( - typeof helloMsg === "string", - "sayHello() output is type of string", - ); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount( - firstHighNetWorthAccount, - ); - const setNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut.success, `getName() SEND invocation produced receipt OK`); - - const { callOutput: getNameOut2 } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut2, - newName, - "setName() invocation #2 output is truthy OK", - ); - - t2.end(); - }); - - test("invoke Web3SigningCredentialType.NONE", async (t2: Test) => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - t2.ok(balance2, "Retrieved balance of test account 2 OK"); - t2.equals( - balance2.toString(), - value.toString(), - "Balance of test account2 is OK", - ); - t2.end(); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - const { callOutput: getNameOut } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal(getNameOut, newName, `getName() output reflects the update OK`); - - const getNameOut2 = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut2, "getName() invocation #2 output is truthy OK"); - - t2.end(); - }); - - test("get prometheus exporter metrics", async (t2: Test) => { - const res = await apiClient.getPrometheusMetricsV1(); - const promMetricsOutput = - "# HELP " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " Total transactions executed\n" + - "# TYPE " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " gauge\n" + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '{type="' + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '"} 3'; - t2.ok(res); - t2.ok(res.data); - t2.equal(res.status, 200); - t2.true( - res.data.includes(promMetricsOutput), - "Total Transaction Count of 3 recorded as expected. RESULT OK.", - ); - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json-json-object-endpoints.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json-json-object-endpoints.test.ts deleted file mode 100644 index 508201eadf..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json-json-object-endpoints.test.ts +++ /dev/null @@ -1,396 +0,0 @@ -import test, { Test } from "tape-promise/tape"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "../../../../../main/typescript/prometheus-exporter/metrics"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, - DefaultApi as EthereumApi, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; - -const testCase = "Ethereum Ledger Connector Plugin"; -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { PluginRegistry } from "@hyperledger/cactus-core"; -import { Server as SocketIoServer } from "socket.io"; - -const logLevel: LogLevelDesc = "INFO"; - -test("BEFORE " + testCase, async (t: Test) => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning didn't throw OK"); - t.end(); -}); - -test(testCase, async (t: Test) => { - const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - await pruneDockerAllIfGithubAction({ logLevel }); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - t.comment( - `Metrics URL: ${apiHost}/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics`, - ); - - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new EthereumApi(apiConfig); - - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - await connector.getOrCreateWebServices(); - await connector.registerWebServices(expressApp, wsApi); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - t.ok(balance, "Retrieved balance of test account OK"); - t.equals( - balance.toString(), - initTransferValue, - "Balance of test account is OK", - ); - - let contractAddress: string; - - test("deploys contract via .json file", async (t2: Test) => { - const deployOut = await apiClient.deployContractSolBytecodeJsonObjectV1({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(deployOut, "deployContract() output is truthy OK"); - t2.ok( - deployOut.data.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t2.ok( - deployOut.data.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - - contractAddress = deployOut.data.transactionReceipt - .contractAddress as string; - t2.ok( - typeof contractAddress === "string", - "contractAddress typeof string OK", - ); - - const helloMsg = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(helloMsg.data.callOutput, "sayHello() output is truthy"); - t2.true( - typeof helloMsg.data.callOutput === "string", - "sayHello() output is type of string", - ); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount( - firstHighNetWorthAccount, - ); - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut.data, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.data.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok( - getNameOut.data.success, - `getName() SEND invocation produced receipt OK`, - ); - - const getNameOut2 = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut2.data.callOutput, - newName, - "setName() invocation #2 output is truthy OK", - ); - - t2.end(); - }); - - test("invoke Web3SigningCredentialType.NONE", async (t2: Test) => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - t2.ok(balance2, "Retrieved balance of test account 2 OK"); - t2.equals( - balance2.toString(), - value.toString(), - "Balance of test account2 is OK", - ); - t2.end(); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount(testEthAccount.address); - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut.data, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - // gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.data.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - // gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut.data.callOutput, - newName, - `getName() output reflects the update OK`, - ); - - const getNameOut2 = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut2.data, "getName() invocation #2 output is truthy OK"); - - t2.end(); - }); - - test("get prometheus exporter metrics", async (t2: Test) => { - const res = await apiClient.getPrometheusMetricsV1(); - const promMetricsOutput = - "# HELP " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " Total transactions executed\n" + - "# TYPE " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " gauge\n" + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '{type="' + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '"} 3'; - t2.ok(res); - t2.ok(res.data); - t2.equal(res.status, 200); - t2.true( - res.data.includes(promMetricsOutput), - "Total Transaction Count of 3 recorded as expected. RESULT OK.", - ); - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json-json-object.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json-json-object.test.ts deleted file mode 100644 index e1b7362aa4..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json-json-object.test.ts +++ /dev/null @@ -1,388 +0,0 @@ -import test, { Test } from "tape-promise/tape"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "../../../../../main/typescript/prometheus-exporter/metrics"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, - DefaultApi as EthereumApi, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; - -const testCase = "Ethereum Ledger Connector Plugin"; -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { PluginRegistry } from "@hyperledger/cactus-core"; -import { Server as SocketIoServer } from "socket.io"; - -const logLevel: LogLevelDesc = "INFO"; - -test("BEFORE " + testCase, async (t: Test) => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning didn't throw OK"); - t.end(); -}); - -test(testCase, async (t: Test) => { - const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - await pruneDockerAllIfGithubAction({ logLevel }); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - t.comment( - `Metrics URL: ${apiHost}/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics`, - ); - - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new EthereumApi(apiConfig); - - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - await connector.getOrCreateWebServices(); - await connector.registerWebServices(expressApp, wsApi); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - t.ok(balance, "Retrieved balance of test account OK"); - t.equals( - balance.toString(), - initTransferValue, - "Balance of test account is OK", - ); - - let contractAddress: string; - - test("deploys contract via .json file", async (t2: Test) => { - const deployOut = await connector.deployContractJsonObject({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(deployOut, "deployContract() output is truthy OK"); - t2.ok( - deployOut.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t2.ok( - deployOut.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - - contractAddress = deployOut.transactionReceipt.contractAddress as string; - t2.ok( - typeof contractAddress === "string", - "contractAddress typeof string OK", - ); - - const { callOutput: helloMsg } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(helloMsg, "sayHello() output is truthy"); - t2.true( - typeof helloMsg === "string", - "sayHello() output is type of string", - ); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount( - firstHighNetWorthAccount, - ); - const setNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut.success, `getName() SEND invocation produced receipt OK`); - - const { callOutput: getNameOut2 } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut2, - newName, - "setName() invocation #2 output is truthy OK", - ); - - t2.end(); - }); - - test("invoke Web3SigningCredentialType.NONE", async (t2: Test) => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - t2.ok(balance2, "Retrieved balance of test account 2 OK"); - t2.equals( - balance2.toString(), - value.toString(), - "Balance of test account2 is OK", - ); - t2.end(); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount(testEthAccount.address); - const setNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - const { callOutput: getNameOut } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal(getNameOut, newName, `getName() output reflects the update OK`); - - const getNameOut2 = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut2, "getName() invocation #2 output is truthy OK"); - - t2.end(); - }); - - test("get prometheus exporter metrics", async (t2: Test) => { - const res = await apiClient.getPrometheusMetricsV1(); - const promMetricsOutput = - "# HELP " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " Total transactions executed\n" + - "# TYPE " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " gauge\n" + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '{type="' + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '"} 3'; - t2.ok(res); - t2.ok(res.data); - t2.equal(res.status, 200); - t2.true( - res.data.includes(promMetricsOutput), - "Total Transaction Count of 3 recorded as expected. RESULT OK.", - ); - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json.test.ts deleted file mode 100644 index 50b34a640a..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v21.4.1-deploy-contract-from-json.test.ts +++ /dev/null @@ -1,444 +0,0 @@ -import Web3 from "web3"; -import { Web3Account } from "web3-eth-accounts"; -import { v4 as uuidV4 } from "uuid"; -import "jest-extended"; -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; - -import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "../../../../../main/typescript/prometheus-exporter/metrics"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialCactusKeychainRef, - Web3SigningCredentialType, - DefaultApi as EthereumApi, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { Server as SocketIoServer } from "socket.io"; - -const testCase = "Ethereum Ledger Connector Plugin"; - -describe(testCase, () => { - const logLevel: LogLevelDesc = "INFO"; - const contractName = "HelloWorld"; - - const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - let addressInfo, - rpcApiHttpHost: string, - ethereumGenesisOptions: IQuorumGenesisOptions, - connector: PluginLedgerConnectorEthereum, - contractAddress: string, - address: string, - port: number, - apiHost, - apiConfig, - apiClient: EthereumApi, - web3: Web3, - testEthAccount: Web3Account, - keychainEntryKey: string, - keychainEntryValue: string, - keychainPlugin: PluginKeychainMemory, - firstHighNetWorthAccount: string; - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - afterAll(async () => await Servers.shutdown(server)); - beforeAll(async () => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await expect(pruning).resolves.toBeTruthy(); - }); - afterAll(async () => { - await ledger.stop(); - await ledger.destroy(); - }); - afterAll(async () => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await expect(pruning).resolves.toBeTruthy(); - }); - - beforeAll(async () => { - await ledger.start(); - rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - expect(rpcApiHttpHost).toBeString(); - - ethereumGenesisOptions = await ledger.getGenesisJsObject(); - expect(ethereumGenesisOptions).toBeTruthy(); - expect(ethereumGenesisOptions.alloc).toBeTruthy(); - - web3 = new Web3(rpcApiHttpHost); - testEthAccount = web3.eth.accounts.create(); - - keychainEntryKey = uuidV4(); - keychainEntryValue = testEthAccount.privateKey; - keychainPlugin = new PluginKeychainMemory({ - instanceId: uuidV4(), - keychainId: uuidV4(), - // pre-provision keychain with mock backend holding the private key of the - // test account that we'll reference while sending requests with the - // signing credential pointing to this keychain entry. - backend: new Map([[keychainEntryKey, keychainEntryValue]]), - logLevel, - }); - connector = new PluginLedgerConnectorEthereum({ - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel: "DEBUG", - pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }), - }); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - ({ address, port } = addressInfo); - apiHost = `http://${address}:${port}`; - apiConfig = new Configuration({ basePath: apiHost }); - apiClient = new EthereumApi(apiConfig); - }); - - test.only("Bootsrap test ETH account with funds from genesis", async () => { - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - [firstHighNetWorthAccount] = highNetWorthAccounts; - keychainPlugin.set( - HelloWorldContractJson.contractName, - JSON.stringify(HelloWorldContractJson), - ); - // Instantiate connector with the keychain plugin that already has the - // private key we want to use for one of our tests - await connector.registerWebServices(expressApp, wsApi); - - const initTransferValue = (10e9).toString(); - const res = await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - console.error("RES:", JSON.stringify(res)); - const balance = await web3.eth.getBalance(testEthAccount.address); - expect(balance).toBeTruthy(); - expect(balance.toString()).toBe(initTransferValue); - }); - - test("deploys contract via .json file", async () => { - const deployOut = await connector.deployContract({ - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - }); - expect(deployOut).toBeTruthy(); - expect(deployOut.transactionReceipt).toBeTruthy(); - expect(deployOut.transactionReceipt.contractAddress).toBeTruthy(); - - contractAddress = deployOut.transactionReceipt.contractAddress as string; - expect(typeof contractAddress).toBe("string"); - - const { callOutput: helloMsg } = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - keychainId: keychainPlugin.getKeychainId(), - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }); - expect(helloMsg).toBeTruthy(); - expect(typeof contractAddress).toBe("string"); - expect(typeof helloMsg).toBe("string"); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async () => { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - }); - expect(setNameOut).toBeTruthy(); - - try { - await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - }); - fail( - "PluginLedgerConnectorEthereum.invokeContract failed to throw error", - ); - } catch (error) { - expect(error).not.toBe("Nonce too low"); - } - - const getNameOut = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }); - expect(getNameOut.success).toBeTruthy(); - - const { callOutput: getNameOut2 } = await connector.getContractInfoKeychain( - { - contractName, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }, - ); - expect(getNameOut2).toEqual(newName); - }); - - test("invoke Web3SigningCredentialType.NONE", async () => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - expect(balance2).toBeTruthy(); - expect(balance2.toString()).toEqual(value.toString()); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async () => { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - }); - expect(setNameOut).toBeTruthy(); - - try { - await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - }); - fail("It should not reach here"); - } catch (error) { - expect(error).not.toBe("Nonce too low"); - } - const { callOutput: getNameOut } = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - }); - expect(getNameOut).toEqual(newName); - - const getNameOut2 = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - }); - expect(getNameOut2).toBeTruthy(); - }); - - test("invoke Web3SigningCredentialType.CactusKeychainRef", async () => { - const newName = `DrCactus${uuidV4()}`; - - const web3SigningCredential: Web3SigningCredentialCactusKeychainRef = { - ethAccount: testEthAccount.address, - keychainEntryKey, - keychainId: keychainPlugin.getKeychainId(), - type: Web3SigningCredentialType.CactusKeychainRef, - }; - - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), - params: [newName], - gas: 1000000, - web3SigningCredential, - nonce: 3, - }); - expect(setNameOut).toBeTruthy(); - - try { - await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - keychainId: keychainPlugin.getKeychainId(), - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 3, - }); - fail("it should not reach here"); - } catch (error) { - expect(error).not.toBe("Nonce too low"); - } - const { callOutput: getNameOut } = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - gas: 1000000, - web3SigningCredential, - }); - expect(getNameOut).toEqual(newName); - - const getNameOut2 = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - gas: 1000000, - web3SigningCredential, - }); - expect(getNameOut2).toBeTruthy(); - }); - - test("get prometheus exporter metrics", async () => { - const res = await apiClient.getPrometheusMetricsV1(); - const promMetricsOutput = - "# HELP " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " Total transactions executed\n" + - "# TYPE " + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - " gauge\n" + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '{type="' + - K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '"} 5'; - expect(res).toBeTruthy(); - expect(res.data).toBeTruthy(); - expect(res.status).toEqual(200); - expect(res.data).toContain(promMetricsOutput); - }); -}); 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 new file mode 100644 index 0000000000..0378e4eeb3 --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-json-object-v1.test.ts @@ -0,0 +1,410 @@ +/** + * Tests for deploying a contract and invoking it's method by directly sending contract JSON. + * + * @note all tests must be run in order, don't use `skip()` or `only()`. @todo - fix that + */ + +////////////////////////////////// +// Constants +////////////////////////////////// + +// Log settings +const testLogLevel: LogLevelDesc = "info"; + +import "jest-extended"; +import express from "express"; +import bodyParser from "body-parser"; +import http from "http"; +import { v4 as uuidV4 } from "uuid"; +import { AddressInfo } from "net"; +import { Server as SocketIoServer } from "socket.io"; +import Web3 from "web3"; +import { Web3Account } from "web3-eth-accounts"; + +import { + LogLevelDesc, + IListenOptions, + Servers, +} from "@hyperledger/cactus-common"; +import { PluginRegistry } from "@hyperledger/cactus-core"; +import { Configuration, Constants } from "@hyperledger/cactus-core-api"; +import { pruneDockerAllIfGithubAction } from "@hyperledger/cactus-test-tooling"; +import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; +import { + GethTestLedger, + WHALE_ACCOUNT_ADDRESS, +} from "@hyperledger/cactus-test-geth-ledger"; + +import HelloWorldContractJson from "../../solidity/hello-world-contract/HelloWorld.json"; +import HelloWorldWithArgContractJson from "../../solidity/hello-world-with-arg-contract/HelloWorldWithArg.json"; +import { + EthContractInvocationType, + PluginLedgerConnectorEthereum, + Web3SigningCredentialType, + DefaultApi as EthereumApi, + DeployContractSolidityBytecodeJsonObjectV1Request, + InvokeContractJsonObjectV1Request, +} from "../../../main/typescript/public-api"; + +describe("Ethereum contract deploy and invoke using keychain tests", () => { + const keychainEntryKey = uuidV4(); + let testEthAccount: Web3Account, + web3: Web3, + addressInfo, + address: string, + port: number, + contractAddress: string, + apiHost, + apiConfig, + ledger: GethTestLedger, + apiClient: EthereumApi, + connector: PluginLedgerConnectorEthereum, + rpcApiHttpHost: string, + keychainPlugin: PluginKeychainMemory; + const expressApp = express(); + expressApp.use(bodyParser.json({ limit: "250mb" })); + const server = http.createServer(expressApp); + const wsApi = new SocketIoServer(server, { + path: Constants.SocketIoConnectionPathV1, + }); + + ////////////////////////////////// + // Setup + ////////////////////////////////// + + beforeAll(async () => { + const pruning = pruneDockerAllIfGithubAction({ logLevel: testLogLevel }); + await expect(pruning).resolves.toBeTruthy(); + + //ledger = new GethTestLedger({ emitContainerLogs: true, testLogLevel }); + ledger = new GethTestLedger({}); + await ledger.start(true); + + const listenOptions: IListenOptions = { + hostname: "0.0.0.0", + port: 0, + server, + }; + addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; + ({ address, port } = addressInfo); + apiHost = `http://${address}:${port}`; + apiConfig = new Configuration({ basePath: apiHost }); + apiClient = new EthereumApi(apiConfig); + rpcApiHttpHost = await ledger.getRpcApiHttpHost(); + web3 = new Web3(rpcApiHttpHost); + testEthAccount = web3.eth.accounts.create(); + + const keychainEntryValue = testEthAccount.privateKey; + keychainPlugin = new PluginKeychainMemory({ + instanceId: uuidV4(), + keychainId: uuidV4(), + // pre-provision keychain with mock backend holding the private key of the + // test account that we'll reference while sending requests with the + // signing credential pointing to this keychain entry. + backend: new Map([[keychainEntryKey, keychainEntryValue]]), + logLevel: testLogLevel, + }); + keychainPlugin.set( + HelloWorldContractJson.contractName, + JSON.stringify(HelloWorldContractJson), + ); + keychainPlugin.set( + HelloWorldWithArgContractJson.contractName, + JSON.stringify(HelloWorldWithArgContractJson), + ); + connector = new PluginLedgerConnectorEthereum({ + instanceId: uuidV4(), + rpcApiHttpHost, + logLevel: testLogLevel, + pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }), + }); + }); + + afterAll(async () => { + await ledger.stop(); + await ledger.destroy(); + await Servers.shutdown(server); + + const pruning = pruneDockerAllIfGithubAction({ logLevel: testLogLevel }); + await expect(pruning).resolves.toBeTruthy(); + }); + + test("setup ethereum connector", async () => { + // Instantiate connector with the keychain plugin that already has the + // private key we want to use for one of our tests + await connector.getOrCreateWebServices(); + await connector.registerWebServices(expressApp, wsApi); + + const initTransferValue = web3.utils.toWei(5000, "ether"); + await apiClient.runTransactionV1({ + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + transactionConfig: { + from: WHALE_ACCOUNT_ADDRESS, + to: testEthAccount.address, + value: initTransferValue, + }, + }); + + const balance = await web3.eth.getBalance(testEthAccount.address); + expect(balance).toBeTruthy(); + expect(balance.toString()).toBe(initTransferValue); + }); + + ////////////////////////////////// + // Deployment Tests + ////////////////////////////////// + + test("deploys contract using json object", async () => { + const deployOut = await apiClient.deployContractSolBytecodeJsonObjectV1({ + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + gas: 1000000, + contractJSON: HelloWorldContractJson, + }); + expect(deployOut).toBeTruthy(); + expect(deployOut.data).toBeTruthy(); + expect(deployOut.data.transactionReceipt).toBeTruthy(); + expect(deployOut.data.transactionReceipt.contractAddress).toBeTruthy(); + + contractAddress = deployOut.data.transactionReceipt + .contractAddress as string; + expect(typeof contractAddress).toBe("string"); + expect(contractAddress).toBeTruthy(); + + const invokeOut = await apiClient.invokeContractV1NoKeychain({ + contractAddress, + invocationType: EthContractInvocationType.Call, + methodName: "sayHello", + params: [], + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + gas: "1000000", + contractJSON: HelloWorldContractJson, + }); + expect(invokeOut).toBeTruthy(); + expect(invokeOut.data).toBeTruthy(); + expect(invokeOut.data.callOutput).toBeTruthy(); + expect(typeof invokeOut.data.callOutput).toBe("string"); + }); + + test("deploys contract using json object with constructorArgs", async () => { + const deployOut = await apiClient.deployContractSolBytecodeJsonObjectV1({ + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + gas: 1000000, + constructorArgs: ["Johnny"], + contractJSON: HelloWorldWithArgContractJson, + }); + expect(deployOut).toBeTruthy(); + expect(deployOut.data).toBeTruthy(); + expect(deployOut.data.transactionReceipt).toBeTruthy(); + expect(deployOut.data.transactionReceipt.contractAddress).toBeTruthy(); + }); + + test("deployContractSolBytecodeJsonObjectV1 without contractJSON should fail", async () => { + try { + await apiClient.deployContractSolBytecodeJsonObjectV1({ + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + gas: 1000000, + } as DeployContractSolidityBytecodeJsonObjectV1Request); + fail( + "Expected deployContractSolBytecodeJsonObjectV1 call to fail but it succeeded.", + ); + } catch (error) { + console.log("deployContractSolBytecodeJsonObjectV1 failed as expected"); + } + }); + + test("deployContractSolBytecodeJsonObjectV1 with additional parameters should fail", async () => { + try { + await apiClient.deployContractSolBytecodeJsonObjectV1({ + 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.", + ); + } catch (error) { + console.log("deployContractSolBytecodeJsonObjectV1 failed as expected"); + } + }); + + ////////////////////////////////// + // Invoke 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, + 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, + invocationType: EthContractInvocationType.Send, + methodName: "setName", + contractAddress, + params: [newName], + gas: "1000000", + 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"); + } + + const getNameOut = await apiClient.invokeContractV1NoKeychain({ + contractJSON: HelloWorldContractJson, + invocationType: EthContractInvocationType.Send, + methodName: "getName", + contractAddress, + params: [], + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + }); + expect(getNameOut).toBeTruthy(); + expect(getNameOut.data).toBeTruthy(); + expect(getNameOut.data.success).toBeTruthy(); + + const invokeGetNameOut = await apiClient.invokeContractV1NoKeychain({ + contractJSON: HelloWorldContractJson, + invocationType: EthContractInvocationType.Call, + methodName: "getName", + contractAddress, + params: [], + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + }); + expect(invokeGetNameOut).toBeTruthy(); + expect(invokeGetNameOut.data).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBe(newName); + }); + + test("invoke Web3SigningCredentialType.PrivateKeyHex", async () => { + const nonce = await web3.eth.getTransactionCount(testEthAccount.address); + const newName = `DrCactus${uuidV4()}`; + const setNameOut = await apiClient.invokeContractV1NoKeychain({ + contractJSON: HelloWorldContractJson, + invocationType: EthContractInvocationType.Send, + methodName: "setName", + contractAddress, + params: [newName], + web3SigningCredential: { + ethAccount: testEthAccount.address, + secret: testEthAccount.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + nonce: nonce.toString(), + }); + expect(setNameOut).toBeTruthy(); + expect(setNameOut.data).toBeTruthy(); + + try { + await apiClient.invokeContractV1NoKeychain({ + contractJSON: HelloWorldContractJson, + invocationType: EthContractInvocationType.Send, + methodName: "setName", + contractAddress, + params: [newName], + gas: "1000000", + web3SigningCredential: { + ethAccount: testEthAccount.address, + 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"); + } + + const invokeGetNameOut = await apiClient.invokeContractV1NoKeychain({ + contractJSON: HelloWorldContractJson, + invocationType: EthContractInvocationType.Call, + methodName: "getName", + contractAddress, + params: [], + gas: "1000000", + web3SigningCredential: { + ethAccount: testEthAccount.address, + secret: testEthAccount.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + }); + expect(invokeGetNameOut).toBeTruthy(); + expect(invokeGetNameOut.data).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBe(newName); + }); + + test("invokeContractV1NoKeychain without methodName should fail", async () => { + try { + await apiClient.invokeContractV1NoKeychain({ + contractJSON: HelloWorldContractJson, + invocationType: EthContractInvocationType.Send, + contractAddress, + params: [`DrCactus${uuidV4()}`], + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + } as InvokeContractJsonObjectV1Request); + fail( + "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", + ); + } catch (error) { + console.log("deployContractSolBytecodeV1 failed as expected"); + } + }); +}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-keychain-v1.test.ts similarity index 58% rename from packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json.test.ts rename to packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-keychain-v1.test.ts index fbfad53197..b970a23455 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/deploy-contract/v2.3.0-deploy-contract-from-json.test.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-contract-deploy-and-invoke-using-keychain-v1.test.ts @@ -1,47 +1,55 @@ +/** + * Tests for deploying a contract and invoking it's method using contract JSON stored in keystore plugin. + * + * @note all tests must be run in order, don't use `skip()` or `only()`. @todo - fix that + */ + +////////////////////////////////// +// Constants +////////////////////////////////// + +// Log settings +const testLogLevel: LogLevelDesc = "info"; + +import "jest-extended"; +import express from "express"; +import bodyParser from "body-parser"; +import http from "http"; +import { v4 as uuidV4 } from "uuid"; +import { AddressInfo } from "net"; +import { Server as SocketIoServer } from "socket.io"; import Web3 from "web3"; import { Web3Account } from "web3-eth-accounts"; -import { v4 as uuidV4 } from "uuid"; -import "jest-extended"; + import { LogLevelDesc, IListenOptions, Servers, } from "@hyperledger/cactus-common"; - +import { PluginRegistry } from "@hyperledger/cactus-core"; +import { Configuration, Constants } from "@hyperledger/cactus-core-api"; +import { pruneDockerAllIfGithubAction } from "@hyperledger/cactus-test-tooling"; import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; +import { + GethTestLedger, + WHALE_ACCOUNT_ADDRESS, +} from "@hyperledger/cactus-test-geth-ledger"; -import HelloWorldContractJson from "../../../solidity/hello-world-contract/HelloWorld.json"; -import HelloWorldWithArgContractJson from "../../../solidity/hello-world-with-arg-contract/HelloWorldWithArg.json"; - -import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "../../../../main/typescript/prometheus-exporter/metrics"; - +import HelloWorldContractJson from "../../solidity/hello-world-contract/HelloWorld.json"; +import HelloWorldWithArgContractJson from "../../solidity/hello-world-with-arg-contract/HelloWorldWithArg.json"; import { EthContractInvocationType, PluginLedgerConnectorEthereum, Web3SigningCredentialCactusKeychainRef, Web3SigningCredentialType, DefaultApi as EthereumApi, -} from "../../../../main/typescript/public-api"; - -import { pruneDockerAllIfGithubAction } from "@hyperledger/cactus-test-tooling"; -import { - GethTestLedger, - WHALE_ACCOUNT_ADDRESS, -} from "@hyperledger/cactus-test-geth-ledger"; -import { PluginRegistry } from "@hyperledger/cactus-core"; -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { Server as SocketIoServer } from "socket.io"; + DeployContractSolidityBytecodeV1Request, + RunTransactionRequest, + InvokeContractV1Request, +} from "../../../main/typescript/public-api"; +import { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT } from "../../../main/typescript/prometheus-exporter/metrics"; -const testCase = "Ethereum Ledger Connector Plugin"; -const BASE_FEE = 0x1ac017b6; - -describe(testCase, () => { - const logLevel: LogLevelDesc = "DEBUG"; - const contractName = "HelloWorld"; +describe("Ethereum contract deploy and invoke using keychain tests", () => { const keychainEntryKey = uuidV4(); let testEthAccount: Web3Account, web3: Web3, @@ -59,35 +67,22 @@ describe(testCase, () => { const expressApp = express(); expressApp.use(bodyParser.json({ limit: "250mb" })); const server = http.createServer(expressApp); - const wsApi = new SocketIoServer(server, { path: Constants.SocketIoConnectionPathV1, }); + ////////////////////////////////// + // Setup + ////////////////////////////////// + beforeAll(async () => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); + const pruning = pruneDockerAllIfGithubAction({ logLevel: testLogLevel }); await expect(pruning).resolves.toBeTruthy(); - }); - beforeAll(async () => { - //ledger = new GethTestLedger({ emitContainerLogs: true, logLevel }); + //ledger = new GethTestLedger({ emitContainerLogs: true, testLogLevel }); ledger = new GethTestLedger({}); await ledger.start(true); - }); - afterAll(async () => { - await ledger.stop(); - await ledger.destroy(); - }); - - afterAll(async () => await Servers.shutdown(server)); - - afterAll(async () => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await expect(pruning).resolves.toBeTruthy(); - }); - - beforeAll(async () => { const listenOptions: IListenOptions = { hostname: "0.0.0.0", port: 0, @@ -110,7 +105,7 @@ describe(testCase, () => { // test account that we'll reference while sending requests with the // signing credential pointing to this keychain entry. backend: new Map([[keychainEntryKey, keychainEntryValue]]), - logLevel, + logLevel: testLogLevel, }); keychainPlugin.set( HelloWorldContractJson.contractName, @@ -123,19 +118,28 @@ describe(testCase, () => { connector = new PluginLedgerConnectorEthereum({ instanceId: uuidV4(), rpcApiHttpHost, - logLevel, + logLevel: testLogLevel, pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }), }); }); - test(testCase, async () => { + afterAll(async () => { + await ledger.stop(); + await ledger.destroy(); + await Servers.shutdown(server); + + const pruning = pruneDockerAllIfGithubAction({ logLevel: testLogLevel }); + await expect(pruning).resolves.toBeTruthy(); + }); + + test("setup ethereum connector", async () => { // Instantiate connector with the keychain plugin that already has the // private key we want to use for one of our tests await connector.getOrCreateWebServices(); await connector.registerWebServices(expressApp, wsApi); const initTransferValue = web3.utils.toWei(5000, "ether"); - await connector.transact({ + await apiClient.runTransactionV1({ web3SigningCredential: { ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", @@ -153,8 +157,12 @@ describe(testCase, () => { expect(balance.toString()).toBe(initTransferValue); }); - test("deploys contract via .json file", async () => { - const deployOut = await connector.deployContract({ + ////////////////////////////////// + // Deployment Tests + ////////////////////////////////// + + test("deploys contract using keychain", async () => { + const deployOut = await apiClient.deployContractSolBytecodeV1({ contractName: HelloWorldContractJson.contractName, keychainId: keychainPlugin.getKeychainId(), web3SigningCredential: { @@ -165,13 +173,15 @@ describe(testCase, () => { gas: 1000000, }); expect(deployOut).toBeTruthy(); - expect(deployOut.transactionReceipt).toBeTruthy(); - expect(deployOut.transactionReceipt.contractAddress).toBeTruthy(); + expect(deployOut.data).toBeTruthy(); + expect(deployOut.data.transactionReceipt).toBeTruthy(); + expect(deployOut.data.transactionReceipt.contractAddress).toBeTruthy(); - contractAddress = deployOut.transactionReceipt.contractAddress as string; + contractAddress = deployOut.data.transactionReceipt + .contractAddress as string; expect(typeof contractAddress).toBe("string"); - const { callOutput: helloMsg } = await connector.getContractInfoKeychain({ - contractName, + const invokeOut = await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Call, methodName: "sayHello", keychainId: keychainPlugin.getKeychainId(), @@ -183,14 +193,79 @@ describe(testCase, () => { }, gas: "1000000", }); - expect(helloMsg).toBeTruthy(); - expect(typeof helloMsg).toBe("string"); + expect(invokeOut).toBeTruthy(); + expect(invokeOut.data).toBeTruthy(); + expect(invokeOut.data.callOutput).toBeTruthy(); + expect(typeof invokeOut.data.callOutput).toBe("string"); + }); + + test("deploys contract using keychain with constructorArgs", async () => { + const deployOut = await apiClient.deployContractSolBytecodeV1({ + contractName: HelloWorldWithArgContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + gas: 1000000, + constructorArgs: ["Johnny"], + }); + expect(deployOut).toBeTruthy(); + expect(deployOut.data).toBeTruthy(); + expect(deployOut.data.transactionReceipt).toBeTruthy(); + expect(deployOut.data.transactionReceipt.contractAddress).toBeTruthy(); + }); + + test("deployContractSolBytecodeV1 without contractName should fail", async () => { + try { + await apiClient.deployContractSolBytecodeV1({ + keychainId: keychainPlugin.getKeychainId(), + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + gas: 1000000, + } as DeployContractSolidityBytecodeV1Request); + fail( + "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", + ); + } catch (error) { + console.log("deployContractSolBytecodeV1 failed as expected"); + } + }); + + test("deployContractSolBytecodeV1 with additional parameters should fail", async () => { + try { + await apiClient.deployContractSolBytecodeV1({ + contractName: HelloWorldContractJson.contractName, + keychainId: keychainPlugin.getKeychainId(), + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + gas: 1000000, + fake: 4, + } as DeployContractSolidityBytecodeV1Request); + fail( + "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", + ); + } catch (error) { + console.log("deployContractSolBytecodeV1 failed as expected"); + } }); + ////////////////////////////////// + // Invoke Tests + ////////////////////////////////// + test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async () => { + const nonce = await web3.eth.getTransactionCount(WHALE_ACCOUNT_ADDRESS); const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, + const setNameOut = await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Send, methodName: "setName", keychainId: keychainPlugin.getKeychainId(), @@ -200,13 +275,14 @@ describe(testCase, () => { secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - nonce: "2", + nonce: nonce.toString(), }); expect(setNameOut).toBeTruthy(); + expect(setNameOut.data).toBeTruthy(); try { - await connector.getContractInfoKeychain({ - contractName, + await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Send, methodName: "setName", keychainId: keychainPlugin.getKeychainId(), @@ -217,15 +293,15 @@ describe(testCase, () => { secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - nonce: "2", + nonce: nonce.toString(), }); fail("Expected getContractInfoKeychain call to fail but it succeeded."); } catch (error) { expect(error).not.toEqual("Nonce too low"); } - const getNameOut = await connector.getContractInfoKeychain({ - contractName, + const getNameOut = await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Send, methodName: "getName", keychainId: keychainPlugin.getKeychainId(), @@ -236,43 +312,45 @@ describe(testCase, () => { type: Web3SigningCredentialType.GethKeychainPassword, }, }); - expect(getNameOut.success).toBeTruthy(); + expect(getNameOut).toBeTruthy(); + expect(getNameOut.data).toBeTruthy(); + expect(getNameOut.data.success).toBeTruthy(); - const { callOutput: getNameOut2 } = await connector.getContractInfoKeychain( - { - contractName, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - web3SigningCredential: { - ethAccount: WHALE_ACCOUNT_ADDRESS, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, + const invokeGetNameOut = await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, + invocationType: EthContractInvocationType.Call, + methodName: "getName", + keychainId: keychainPlugin.getKeychainId(), + params: [], + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, }, - ); - expect(getNameOut2).toBe(newName); + }); + expect(invokeGetNameOut).toBeTruthy(); + expect(invokeGetNameOut.data).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBe(newName); }); test("invoke Web3SigningCredentialType.NONE", async () => { const testEthAccount2 = web3.eth.accounts.create(); const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( { from: testEthAccount.address, to: testEthAccount2.address, value, maxPriorityFeePerGas: 0, - maxFeePerGas: BASE_FEE, + maxFeePerGas: 0x40000000, gasLimit: 21000, }, testEthAccount.privateKey, ); - await connector.transact({ + await apiClient.runTransactionV1({ web3SigningCredential: { type: Web3SigningCredentialType.None, }, @@ -286,10 +364,26 @@ describe(testCase, () => { expect(balance2.toString()).toBe(value.toString()); }); + test("runTransactionV1 without transaction config should fail", async () => { + try { + await apiClient.runTransactionV1({ + web3SigningCredential: { + type: Web3SigningCredentialType.None, + }, + } as RunTransactionRequest); + fail( + "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", + ); + } catch (error) { + console.log("deployContractSolBytecodeV1 failed as expected"); + } + }); + test("invoke Web3SigningCredentialType.PrivateKeyHex", async () => { + const nonce = await web3.eth.getTransactionCount(testEthAccount.address); const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, + const setNameOut = await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Send, methodName: "setName", keychainId: keychainPlugin.getKeychainId(), @@ -299,13 +393,14 @@ describe(testCase, () => { secret: testEthAccount.privateKey, type: Web3SigningCredentialType.PrivateKeyHex, }, - nonce: "1", + nonce: nonce.toString(), }); expect(setNameOut).toBeTruthy(); + expect(setNameOut.data).toBeTruthy(); try { - await connector.getContractInfoKeychain({ - contractName, + await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Send, methodName: "setName", keychainId: keychainPlugin.getKeychainId(), @@ -316,15 +411,15 @@ describe(testCase, () => { secret: testEthAccount.privateKey, type: Web3SigningCredentialType.PrivateKeyHex, }, - nonce: "1", + nonce: nonce.toString(), }); fail("Expected getContractInfoKeychain call to fail but it succeeded."); } catch (error) { expect(error).not.toEqual("Nonce too low"); } - const { callOutput: getNameOut } = await connector.getContractInfoKeychain({ - contractName, + const invokeGetNameOut = await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Call, methodName: "getName", keychainId: keychainPlugin.getKeychainId(), @@ -336,26 +431,15 @@ describe(testCase, () => { type: Web3SigningCredentialType.PrivateKeyHex, }, }); - expect(getNameOut).toBe(newName); - - const getNameOut2 = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - gas: "1000000", - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - }); - expect(getNameOut2).toBeTruthy(); + expect(invokeGetNameOut).toBeTruthy(); + expect(invokeGetNameOut.data).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBe(newName); }); test("invoke Web3SigningCredentialType.CactusKeychainRef", async () => { const newName = `DrCactus${uuidV4()}`; + const nonce = await web3.eth.getTransactionCount(testEthAccount.address); const web3SigningCredential: Web3SigningCredentialCactusKeychainRef = { ethAccount: testEthAccount.address, @@ -364,21 +448,23 @@ describe(testCase, () => { type: Web3SigningCredentialType.CactusKeychainRef, }; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, + // @todo - using too large nonce freezes the test! Fix that + const setNameOut = await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Send, methodName: "setName", keychainId: keychainPlugin.getKeychainId(), params: [newName], gas: "1000000", web3SigningCredential, - nonce: "3", + nonce: nonce.toString(), }); expect(setNameOut).toBeTruthy(); + expect(setNameOut.data).toBeTruthy(); try { - await connector.getContractInfoKeychain({ - contractName, + await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Send, methodName: "setName", keychainId: keychainPlugin.getKeychainId(), @@ -389,15 +475,15 @@ describe(testCase, () => { secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, - nonce: "3", + nonce: nonce.toString(), }); fail("Expected getContractInfoKeychain call to fail but it succeeded."); } catch (error) { expect(error).not.toEqual("Nonce too low"); } - const { callOutput: getNameOut } = await connector.getContractInfoKeychain({ - contractName, + const invokeGetNameOut = await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, invocationType: EthContractInvocationType.Call, methodName: "getName", keychainId: keychainPlugin.getKeychainId(), @@ -405,20 +491,34 @@ describe(testCase, () => { gas: "1000000", web3SigningCredential, }); - expect(getNameOut).toContain(newName); + expect(invokeGetNameOut).toBeTruthy(); + expect(invokeGetNameOut.data).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBeTruthy(); + expect(invokeGetNameOut.data.callOutput).toBe(newName); + }); - const getNameOut2 = await connector.getContractInfoKeychain({ - contractName, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - keychainId: keychainPlugin.getKeychainId(), - params: [], - gas: "1000000", - web3SigningCredential, - }); - expect(getNameOut2).toBeTruthy(); + test("invokeContractV1 without methodName should fail", async () => { + try { + await apiClient.invokeContractV1({ + contractName: HelloWorldContractJson.contractName, + invocationType: EthContractInvocationType.Send, + keychainId: keychainPlugin.getKeychainId(), + params: [`DrCactus${uuidV4()}`], + web3SigningCredential: { + ethAccount: WHALE_ACCOUNT_ADDRESS, + secret: "", + type: Web3SigningCredentialType.GethKeychainPassword, + }, + } as InvokeContractV1Request); + fail( + "Expected deployContractSolBytecodeV1 call to fail but it succeeded.", + ); + } catch (error) { + console.log("deployContractSolBytecodeV1 failed as expected"); + } }); + // @todo - move to separate test suite test("get prometheus exporter metrics", async () => { const res = await apiClient.getPrometheusMetricsV1(); const promMetricsOutput = @@ -431,31 +531,10 @@ describe(testCase, () => { K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + '{type="' + K_CACTUS_ETHEREUM_TOTAL_TX_COUNT + - '"} 5'; + '"} 3'; expect(res); expect(res.data); expect(res.status).toEqual(200); expect(res.data).toContain(promMetricsOutput); }); - - test("deploys contract via .json file with constructorArgs", async () => { - const deployOut = await connector.deployContract({ - contractName: HelloWorldWithArgContractJson.contractName, - contractJSON: HelloWorldWithArgContractJson, - keychainId: keychainPlugin.getKeychainId(), - web3SigningCredential: { - ethAccount: WHALE_ACCOUNT_ADDRESS, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - constructorArgs: ["Johnny"], - }); - expect(deployOut).toBeTruthy(); - expect(deployOut.transactionReceipt).toBeTruthy(); - expect(deployOut.transactionReceipt.contractAddress).toBeTruthy(); - - contractAddress = deployOut.transactionReceipt.contractAddress as string; - expect(contractAddress).toBeString(); - }); }); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-web3-contract-v1.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-contract-v1.test.ts similarity index 78% rename from packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-web3-contract-v1.test.ts rename to packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-contract-v1.test.ts index dc76b86e18..e9da502b9f 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-web3-contract-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-contract-v1.test.ts @@ -10,8 +10,6 @@ const testLogLevel = "info"; const sutLogLevel = "info"; -const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - import "jest-extended"; import { v4 as uuidv4 } from "uuid"; import { PluginRegistry } from "@hyperledger/cactus-core"; @@ -20,30 +18,28 @@ import { InvokeRawWeb3EthContractV1Request, PluginLedgerConnectorEthereum, Web3SigningCredentialType, -} from "../../../../../main/typescript/index"; +} from "../../../main/typescript/index"; +import { pruneDockerAllIfGithubAction } from "@hyperledger/cactus-test-tooling"; import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; + GethTestLedger, + WHALE_ACCOUNT_ADDRESS, +} from "@hyperledger/cactus-test-geth-ledger"; import { Logger, LoggerProvider } from "@hyperledger/cactus-common"; -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; +import HelloWorldContractJson from "../../solidity/hello-world-contract/HelloWorld.json"; import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; import { ContractAbi } from "web3"; // Unit Test logger setup const log: Logger = LoggerProvider.getOrCreate({ - label: "v21.4.1-invoke-web3-contract-v1.test", + label: "geth-invoke-web3-contract-v1.test", level: testLogLevel, }); log.info("Test started"); describe("invokeRawWeb3EthContract Tests", () => { - let ethereumTestLedger: QuorumTestLedger; + let ethereumTestLedger: GethTestLedger; let connector: PluginLedgerConnectorEthereum; - let firstHighNetWorthAccount: string; let contractAbi: ContractAbi; let contractAddress: string; @@ -55,26 +51,10 @@ describe("invokeRawWeb3EthContract Tests", () => { log.info("Prune Docker..."); await pruneDockerAllIfGithubAction({ logLevel: testLogLevel }); - log.info("Start QuorumTestLedger..."); - log.debug("Ethereum version:", containerImageVersion); - ethereumTestLedger = new QuorumTestLedger({ - containerImageVersion, - }); - await ethereumTestLedger.start(); - - log.info("Get highNetWorthAccounts..."); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ethereumTestLedger.getGenesisJsObject(); - expect(ethereumGenesisOptions).toBeTruthy(); - expect(ethereumGenesisOptions.alloc).toBeTruthy(); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - [firstHighNetWorthAccount] = highNetWorthAccounts; + log.info("Start GethTestLedger..."); + // log.debug("Ethereum version:", containerImageVersion); + ethereumTestLedger = new GethTestLedger({}); + await ethereumTestLedger.start(true); const rpcApiHttpHost = await ethereumTestLedger.getRpcApiHttpHost(); log.debug("rpcApiHttpHost:", rpcApiHttpHost); @@ -103,7 +83,7 @@ describe("invokeRawWeb3EthContract Tests", () => { contractName: HelloWorldContractJson.contractName, keychainId: keychainPlugin.getKeychainId(), web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, + ethAccount: WHALE_ACCOUNT_ADDRESS, secret: "", type: Web3SigningCredentialType.GethKeychainPassword, }, @@ -135,7 +115,7 @@ describe("invokeRawWeb3EthContract Tests", () => { // 1. Set new value (send) const sendInvocationArgs = { - from: firstHighNetWorthAccount, + from: WHALE_ACCOUNT_ADDRESS, }; const sendInvokeArgs: InvokeRawWeb3EthContractV1Request = { @@ -151,7 +131,7 @@ describe("invokeRawWeb3EthContract Tests", () => { sendInvokeArgs, ); expect(resultsSend).toBeTruthy(); - expect(resultsSend.status).toBeTrue(); + expect(resultsSend.status.toString()).toEqual("1"); // // 2. Get new, updated value (call) const callInvokeArgs: InvokeRawWeb3EthContractV1Request = { diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-web3-method-v1.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-method-v1.test.ts similarity index 82% rename from packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-web3-method-v1.test.ts rename to packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-method-v1.test.ts index 70b75dfd5f..6db960c88f 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-web3-method-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/geth-invoke-web3-method-v1.test.ts @@ -10,28 +10,27 @@ const testLogLevel = "info"; const sutLogLevel = "info"; -const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - import "jest-extended"; import { v4 as uuidv4 } from "uuid"; import { PluginRegistry } from "@hyperledger/cactus-core"; -import { PluginLedgerConnectorEthereum } from "../../../../../main/typescript/index"; -import { - QuorumTestLedger, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; +import { PluginLedgerConnectorEthereum } from "../../../main/typescript/index"; +import { pruneDockerAllIfGithubAction } from "@hyperledger/cactus-test-tooling"; import { Logger, LoggerProvider } from "@hyperledger/cactus-common"; +import { + GethTestLedger, + WHALE_ACCOUNT_ADDRESS, +} from "@hyperledger/cactus-test-geth-ledger"; import Web3 from "web3"; // Unit Test logger setup const log: Logger = LoggerProvider.getOrCreate({ - label: "v21.4.1-invoke-web3-method-v1.test", + label: "geth-invoke-web3-method-v1.test", level: testLogLevel, }); log.info("Test started"); describe("invokeRawWeb3EthMethod Tests", () => { - let ethereumTestLedger: QuorumTestLedger; + let ethereumTestLedger: GethTestLedger; let connector: PluginLedgerConnectorEthereum; let web3: Web3; @@ -43,12 +42,10 @@ describe("invokeRawWeb3EthMethod Tests", () => { log.info("Prune Docker..."); await pruneDockerAllIfGithubAction({ logLevel: testLogLevel }); - log.info("Start QuorumTestLedger..."); - log.debug("Ethereum version:", containerImageVersion); - ethereumTestLedger = new QuorumTestLedger({ - containerImageVersion, - }); - await ethereumTestLedger.start(); + log.info("Start GethTestLedger..."); + // log.debug("Ethereum version:", containerImageVersion); + ethereumTestLedger = new GethTestLedger({}); + await ethereumTestLedger.start(true); const rpcApiHttpHost = await ethereumTestLedger.getRpcApiHttpHost(); log.debug("rpcApiHttpHost:", rpcApiHttpHost); @@ -81,7 +78,7 @@ describe("invokeRawWeb3EthMethod Tests", () => { methodName: "getGasPrice", }); expect(connectorResponse).toBeTruthy(); - expect(connectorResponse).toEqual("0"); // gas is free on ethereum + expect(Number(connectorResponse)).toBeGreaterThan(0); }); test("invokeRawWeb3EthMethod with 1-argument method works (getBlock)", async () => { @@ -99,17 +96,16 @@ describe("invokeRawWeb3EthMethod Tests", () => { }); test("invokeRawWeb3EthMethod with 2-argument method works (getStorageAt)", async () => { - const genesisAccount = await ethereumTestLedger.getGenesisAccount(); - log.debug("genesisAccount:", genesisAccount); + log.debug("WHALE_ACCOUNT_ADDRESS:", WHALE_ACCOUNT_ADDRESS); const connectorResponse = await connector.invokeRawWeb3EthMethod({ methodName: "getStorageAt", - params: [genesisAccount, 0], + params: [WHALE_ACCOUNT_ADDRESS, 0], }); expect(connectorResponse).toBeTruthy(); // Compare with direct web3 response - const web3Response = await web3.eth.getStorageAt(genesisAccount, 0); + const web3Response = await web3.eth.getStorageAt(WHALE_ACCOUNT_ADDRESS, 0); expect(web3Response).toBeTruthy(); expect(web3Response).toEqual(connectorResponse); }); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/openapi/openapi-validation-no-keychain.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/openapi/openapi-validation-no-keychain.test.ts deleted file mode 100644 index cab629aa34..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/openapi/openapi-validation-no-keychain.test.ts +++ /dev/null @@ -1,323 +0,0 @@ -import test, { Test } from "tape-promise/tape"; -import { v4 as uuidV4 } from "uuid"; - -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, - DefaultApi as EthereumApi, - DeployContractSolidityBytecodeJsonObjectV1Request, - InvokeContractJsonObjectV1Request, -} from "../../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; - -const testCase = "Ethereum Ledger Connector Plugin"; -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { PluginRegistry } from "@hyperledger/cactus-core"; -import { Server as SocketIoServer } from "socket.io"; - -import { installOpenapiValidationMiddleware } from "@hyperledger/cactus-core"; -import OAS from "../../../../../../main/json/openapi.json"; - -const logLevel: LogLevelDesc = "INFO"; - -test("BEFORE " + testCase, async (t: Test) => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning didn't throw OK"); - t.end(); -}); - -test(testCase, async (t: Test) => { - const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - await pruneDockerAllIfGithubAction({ logLevel }); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - t.comment( - `Metrics URL: ${apiHost}/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics`, - ); - - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new EthereumApi(apiConfig); - - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - await installOpenapiValidationMiddleware({ - logLevel, - app: expressApp, - apiSpec: OAS, - }); - - await connector.getOrCreateWebServices(); - await connector.registerWebServices(expressApp, wsApi); - - const fDeploy = "deployContractSolBytecodeJsonObjectV1"; - const fInvoke = "invokeContractV1NoKeychain"; - const cOk = "without bad request error"; - const cWithoutParams = "not sending all required parameters"; - const cInvalidParams = "sending invalid parameters"; - - let contractAddress: string; - - test(`${testCase} - ${fDeploy} - ${cOk}`, async (t2: Test) => { - const parameters = { - contractAddress, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - // bytecode: HelloWorldContractJson.bytecode, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }; - const res = await apiClient.deployContractSolBytecodeJsonObjectV1( - parameters as DeployContractSolidityBytecodeJsonObjectV1Request, - ); - t2.ok(res, "Contract deployed successfully"); - t2.ok(res.data); - t2.equal( - res.status, - 200, - `Endpoint ${fDeploy}: response.status === 200 OK`, - ); - - contractAddress = res.data.transactionReceipt.contractAddress as string; - - t2.end(); - }); - - test(`${testCase} - ${fInvoke} - ${cOk}`, async (t2: Test) => { - const parameters = { - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [`DrCactus${uuidV4()}`], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }; - const res = await apiClient.invokeContractV1NoKeychain( - parameters as InvokeContractJsonObjectV1Request, - ); - t2.ok(res, "Contract invoked successfully"); - t2.ok(res.data); - t2.equal( - res.status, - 200, - `Endpoint ${fInvoke}: response.status === 200 OK`, - ); - - t2.end(); - }); - - test(`${testCase} - ${fDeploy} - ${cWithoutParams}`, async (t2: Test) => { - try { - const parameters = { - contractAddress, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - bytecode: HelloWorldContractJson.bytecode, - gas: 1000000, - }; - await apiClient.deployContractSolBytecodeJsonObjectV1( - (parameters as any) as DeployContractSolidityBytecodeJsonObjectV1Request, - ); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fDeploy} without required contractJSON and bytecode: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: any) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("contractJSON"), - "Rejected because contractJSON is required", - ); - t2.notOk(fields.includes("gas"), "gas is not required"); - } - - t2.end(); - }); - - test(`${testCase} - ${fDeploy} - ${cInvalidParams}`, async (t2: Test) => { - try { - const parameters = { - contractAddress, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - bytecode: HelloWorldContractJson.bytecode, - gas: 1000000, - contractJSON: HelloWorldContractJson, - fake: 4, - }; - await apiClient.deployContractSolBytecodeJsonObjectV1( - (parameters as any) as DeployContractSolidityBytecodeJsonObjectV1Request, - ); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fDeploy} with fake=4: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: any) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); - } - - t2.end(); - }); - - test(`${testCase} - ${fInvoke} - ${cWithoutParams}`, async (t2: Test) => { - try { - const parameters = { - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [`DrCactus${uuidV4()}`], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - }; - await apiClient.invokeContractV1NoKeychain( - (parameters as any) as InvokeContractJsonObjectV1Request, - ); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fInvoke} without required contractJSON and methodName: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: any) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("contractJSON"), - "Rejected because contractJSON is required", - ); - t2.notOk(fields.includes("nonce"), "nonce is not required"); - } - - t2.end(); - }); - - test(`${testCase} - ${fInvoke} - ${cInvalidParams}`, async (t2: Test) => { - try { - const parameters = { - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [`DrCactus${uuidV4()}`], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - fake: 4, - }; - await apiClient.invokeContractV1NoKeychain( - (parameters as any) as InvokeContractJsonObjectV1Request, - ); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fInvoke} with fake=4: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: any) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); - } - - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/openapi/openapi-validation.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/openapi/openapi-validation.test.ts deleted file mode 100644 index 41f43ae322..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/openapi/openapi-validation.test.ts +++ /dev/null @@ -1,427 +0,0 @@ -import test, { Test } from "tape-promise/tape"; -import { v4 as uuidV4 } from "uuid"; -import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; -import HelloWorldContractJson from "../../../../../solidity/hello-world-contract/HelloWorld.json"; -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, - DefaultApi as EthereumApi, - DeployContractSolidityBytecodeV1Request, - InvokeContractV1Request, - RunTransactionRequest, -} from "../../../../../../main/typescript/public-api"; -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, - pruneDockerAllIfGithubAction, -} from "@hyperledger/cactus-test-tooling"; -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; -import { PluginRegistry } from "@hyperledger/cactus-core"; -import { AddressInfo } from "net"; -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { Server as SocketIoServer } from "socket.io"; - -import { installOpenapiValidationMiddleware } from "@hyperledger/cactus-core"; -import OAS from "../../../../../../main/json/openapi.json"; - -const logLevel: LogLevelDesc = "INFO"; -const testCase = "Ethereum API"; - -test("BEFORE " + testCase, async (t: Test) => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning did not throw OK"); - t.end(); -}); - -test(testCase, async (t: Test) => { - // create the test ethereumTestLedger - const containerImageVersion = "2021-01-08-7a055c3"; // Quorum v2.3.0, Tessera v0.10.0 - - const ledgerOptions = { containerImageVersion }; - const ethereumTestLedger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ethereumTestLedger.stop(); - await ethereumTestLedger.destroy(); - }); - await ethereumTestLedger.start(); - - // retrieve host to which connector will attack - const rpcApiHttpHost = await ethereumTestLedger.getRpcApiHttpHost(); - - // obtain accounts from genesis - const ethereumGenesisOptions: IQuorumGenesisOptions = await ethereumTestLedger.getGenesisJsObject(); - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - // create a new account - const testEthAccount = await ethereumTestLedger.createEthTestAccount(); - - // create the keychain plugin for recently created account - const keychainEntryKey = uuidV4(); - const keychainId = uuidV4(); - const keychainEntryValue = testEthAccount.privateKey; - const keychainPlugin = new PluginKeychainMemory({ - instanceId: uuidV4(), - keychainId, - backend: new Map([[keychainEntryKey, keychainEntryValue]]), - logLevel, - }); - keychainPlugin.set( - HelloWorldContractJson.contractName, - JSON.stringify(HelloWorldContractJson), - ); - - // create a plugin registry with the recently created keychain plugin - const pluginRegistry = new PluginRegistry({ - plugins: [keychainPlugin], - }); - - // create the connector including test ledger host and plugin registry - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry, - }, - ); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new EthereumApi(apiConfig); - - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - await installOpenapiValidationMiddleware({ - logLevel, - app: expressApp, - apiSpec: OAS, - }); - - await connector.getOrCreateWebServices(); - await connector.registerWebServices(expressApp, wsApi); - - const fDeploy = "apiV1EthereumDeployContractSolidityBytecode"; - const fInvoke = "apiV1EthereumInvokeContract"; - const fRun = "apiV1EthereumRunTransaction"; - const cOk = "without bad request error"; - const cWithoutParams = "not sending all required parameters"; - const cInvalidParams = "sending invalid parameters"; - - let contractAddress: string; - - test(`${testCase} - ${fDeploy} - ${cOk}`, async (t2: Test) => { - const parameters = { - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - }; - const res = await apiClient.deployContractSolBytecodeV1( - parameters as DeployContractSolidityBytecodeV1Request, - ); - t2.ok(res, "Contract deployed successfully"); - t2.ok(res.data); - t2.equal( - res.status, - 200, - `Endpoint ${fDeploy}: response.status === 200 OK`, - ); - - contractAddress = res.data.transactionReceipt.contractAddress as string; - - t2.end(); - }); - - test(`${testCase} - ${fDeploy} - ${cWithoutParams}`, async (t2: Test) => { - try { - const parameters = { - keychainId: keychainPlugin.getKeychainId(), - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }; - await apiClient.deployContractSolBytecodeV1( - parameters as DeployContractSolidityBytecodeV1Request, - ); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fDeploy} without required contractName and bytecode: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: any) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("contractName"), - "Rejected because contractName is required", - ); - t2.notOk(fields.includes("gas"), "gas is not required"); - } - - t2.end(); - }); - - test(`${testCase} - ${fDeploy} - ${cInvalidParams}`, async (t2: Test) => { - try { - const parameters = { - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - fake: 4, - }; - await apiClient.deployContractSolBytecodeV1( - parameters as DeployContractSolidityBytecodeV1Request, - ); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fDeploy} with fake=4: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: any) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); - } - - t2.end(); - }); - - test(`${testCase} - ${fInvoke} - ${cOk}`, async (t2: Test) => { - const parameters = { - contractName: HelloWorldContractJson.contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [`DrCactus${uuidV4()}`], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - }; - const res = await apiClient.invokeContractV1( - parameters as InvokeContractV1Request, - ); - t2.ok(res, "Contract invoked successfully"); - t2.ok(res.data); - t2.equal( - res.status, - 200, - `Endpoint ${fInvoke}: response.status === 200 OK`, - ); - - t2.end(); - }); - - test(`${testCase} - ${fInvoke} - ${cWithoutParams}`, async (t2: Test) => { - try { - const parameters = { - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - params: [`DrCactus${uuidV4()}`], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }; - await apiClient.invokeContractV1(parameters as InvokeContractV1Request); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fInvoke} without required methodName: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: any) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("methodName"), - "Rejected because methodName is required", - ); - t2.notOk(fields.includes("nonce"), "nonce is not required"); - } - - t2.end(); - }); - - test(`${testCase} - ${fInvoke} - ${cInvalidParams}`, async (t2: Test) => { - try { - const parameters = { - contractName: HelloWorldContractJson.contractName, - contractAddress, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [`DrCactus${uuidV4()}`], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - fake: 4, - }; - await apiClient.invokeContractV1(parameters as InvokeContractV1Request); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fInvoke} with fake=4: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: any) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); - } - - t2.end(); - }); - - test(`${testCase} - ${fRun} - ${cOk}`, async (t2: Test) => { - const parameters = { - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: 10e9, - }, - }; - const res = await apiClient.runTransactionV1( - parameters as RunTransactionRequest, - ); - t2.ok(res, "Transaction executed successfully"); - t2.ok(res.data); - t2.equal(res.status, 200, `Endpoint ${fRun}: response.status === 200 OK`); - - t2.end(); - }); - - test(`${testCase} - ${fRun} - ${cWithoutParams}`, async (t2: Test) => { - try { - const parameters = { - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }; - await apiClient.runTransactionV1(parameters as RunTransactionRequest); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fRun} without required transactionConfig: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: { path: string }) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("transactionConfig"), - "Rejected because transactionConfig is required", - ); - t2.notOk(fields.includes("timeoutMs"), "timeoutMs is not required"); - } - - t2.end(); - }); - - test(`${testCase} - ${fRun} - ${cInvalidParams}`, async (t2: Test) => { - try { - const parameters = { - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: 10e9, - }, - fake: 4, - }; - await apiClient.runTransactionV1(parameters as RunTransactionRequest); - } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fRun} with fake=4: response.status === 400 OK`, - ); - const fields = e.response.data.map((param: { path: string }) => - param.path.replace(".body.", ""), - ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); - } - - t2.end(); - }); - - t.end(); -}); - -test("AFTER " + testCase, async (t: Test) => { - const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning did not throw OK"); - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract-json-object-endpoints.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract-json-object-endpoints.test.ts deleted file mode 100644 index 75e7e80268..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract-json-object-endpoints.test.ts +++ /dev/null @@ -1,367 +0,0 @@ -import test, { Test } from "tape"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../solidity/hello-world-contract/HelloWorld.json"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, - DefaultApi as EthereumApi, -} from "../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; - -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { Server as SocketIoServer } from "socket.io"; - -const logLevel: LogLevelDesc = "INFO"; - -test("Ethereum Ledger Connector Plugin", async (t: Test) => { - const containerImageVersion = "2021-01-08-7a055c3"; // Quorum v2.3.0, Tessera v0.10.0 - - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - t.comment( - `Metrics URL: ${apiHost}/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics`, - ); - - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new EthereumApi(apiConfig); - - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - await connector.getOrCreateWebServices(); - await connector.registerWebServices(expressApp, wsApi); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - t.ok(balance, "Retrieved balance of test account OK"); - t.equals( - balance.toString(), - initTransferValue, - "Balance of test account is OK", - ); - - let contractAddress: string; - - test("deploys contract via .json file", async (t2: Test) => { - const deployOut = await apiClient.deployContractSolBytecodeJsonObjectV1({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(deployOut, "deployContract() output is truthy OK"); - t2.ok( - deployOut.data.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t2.ok( - deployOut.data.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - - contractAddress = deployOut.data.transactionReceipt - .contractAddress as string; - t2.ok( - typeof contractAddress === "string", - "contractAddress typeof string OK", - ); - - const helloMsgRes = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(helloMsgRes.data.callOutput, "sayHello() output is truthy"); - t2.true( - typeof helloMsgRes.data.callOutput === "string", - "sayHello() output is type of string", - ); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount( - firstHighNetWorthAccount, - ); - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.data.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok( - getNameOut.data.success, - `getName() SEND invocation produced receipt OK`, - ); - - const getNameOut2 = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut2.data.callOutput, - newName, - "setName() invocation #2 output is truthy OK", - ); - - t2.end(); - }); - - test("invoke Web3SigningCredentialType.NONE", async (t2: Test) => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - t2.ok(balance2, "Retrieved balance of test account 2 OK"); - t2.equals( - balance2.toString(), - value.toString(), - "Balance of test account2 is OK", - ); - t2.end(); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.data.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut.data.callOutput, - newName, - `getName() output reflects the update OK`, - ); - - const getNameOut2 = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut2.data, "getName() invocation #2 output is truthy OK"); - - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract-json-object.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract-json-object.test.ts deleted file mode 100644 index d909fd2fc0..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract-json-object.test.ts +++ /dev/null @@ -1,320 +0,0 @@ -import test, { Test } from "tape"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { LogLevelDesc } from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; - -const logLevel: LogLevelDesc = "INFO"; - -test("Ethereum Ledger Connector Plugin", async (t: Test) => { - const containerImageVersion = "2021-01-08-7a055c3"; // Quorum v2.3.0, Tessera v0.10.0 - - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - t.ok(balance, "Retrieved balance of test account OK"); - t.equals( - balance.toString(), - initTransferValue, - "Balance of test account is OK", - ); - - let contractAddress: string; - - test("deploys contract via .json file", async (t2: Test) => { - const deployOut = await connector.deployContractJsonObject({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(deployOut, "deployContract() output is truthy OK"); - t2.ok( - deployOut.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t2.ok( - deployOut.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - - contractAddress = deployOut.transactionReceipt.contractAddress as string; - t2.ok( - typeof contractAddress === "string", - "contractAddress typeof string OK", - ); - - const { callOutput: helloMsg } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(helloMsg, "sayHello() output is truthy"); - t2.true( - typeof helloMsg === "string", - "sayHello() output is type of string", - ); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount( - firstHighNetWorthAccount, - ); - const setNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut.success, `getName() SEND invocation produced receipt OK`); - - const { callOutput: getNameOut2 } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut2, - newName, - "setName() invocation #2 output is truthy OK", - ); - - t2.end(); - }); - - test("invoke Web3SigningCredentialType.NONE", async (t2: Test) => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - t2.ok(balance2, "Retrieved balance of test account 2 OK"); - t2.equals( - balance2.toString(), - value.toString(), - "Balance of test account2 is OK", - ); - t2.end(); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - const { callOutput: getNameOut } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal(getNameOut, newName, `getName() output reflects the update OK`); - - const getNameOut2 = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut2, "getName() invocation #2 output is truthy OK"); - - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract.test.ts deleted file mode 100644 index b10b7d54f5..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v2.3.0-invoke-contract.test.ts +++ /dev/null @@ -1,382 +0,0 @@ -import Web3 from "web3"; -import "jest-extended"; -import { Web3Account } from "web3-eth-accounts"; -import { v4 as uuidV4 } from "uuid"; - -import { LogLevelDesc } from "@hyperledger/cactus-common"; - -import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialCactusKeychainRef, - Web3SigningCredentialType, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; - -const logLevel: LogLevelDesc = "INFO"; -const contractName = "HelloWorld"; -const testcase = ""; - -describe(testcase, () => { - const containerImageVersion = "2021-01-08-7a055c3"; // Quorum v2.3.0, Tessera v0.10.0 - - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - const keychainEntryKey = uuidV4(); - - let contractAddress: string, - connector: PluginLedgerConnectorEthereum, - rpcApiHttpHost: string, - web3: Web3, - keychainPlugin: PluginKeychainMemory, - testEthAccount: Web3Account, - ethereumGenesisOptions: IQuorumGenesisOptions, - highNetWorthAccounts: string[], - firstHighNetWorthAccount: string; - - afterAll(async () => { - await ledger.stop(); - await ledger.destroy(); - }); - - beforeAll(async () => { - await ledger.start(); - rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - web3 = new Web3(rpcApiHttpHost); - testEthAccount = web3.eth.accounts.create(); - - const keychainEntryValue = testEthAccount.privateKey; - keychainPlugin = new PluginKeychainMemory({ - instanceId: uuidV4(), - keychainId: uuidV4(), - // pre-provision keychain with mock backend holding the private key of the - // test account that we'll reference while sending requests with the - // signing credential pointing to this keychain entry. - backend: new Map([[keychainEntryKey, keychainEntryValue]]), - logLevel, - }); - ethereumGenesisOptions = await ledger.getGenesisJsObject(); - highNetWorthAccounts = Object.keys(ethereumGenesisOptions.alloc).filter( - (address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }, - ); - [firstHighNetWorthAccount] = highNetWorthAccounts; - - connector = new PluginLedgerConnectorEthereum({ - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }), - }); - }); - - test("Ethereum Ledger Connector Plugin", async () => { - expect(ethereumGenesisOptions).toBeTruthy(); - expect(ethereumGenesisOptions.alloc).toBeTruthy(); - - keychainPlugin.set( - HelloWorldContractJson.contractName, - JSON.stringify(HelloWorldContractJson), - ); - // Instantiate connector with the keychain plugin that already has the - // private key we want to use for one of our tests - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - expect(balance).toBeTruthy(); - expect(balance.toString()).toEqual(initTransferValue); - }); - - test("deploys contract via .json file", async () => { - const deployOut = await connector.deployContract({ - keychainId: keychainPlugin.getKeychainId(), - contractName: HelloWorldContractJson.contractName, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - }); - expect(deployOut).toBeTruthy(); - expect(deployOut.transactionReceipt).toBeTruthy(); - expect(deployOut.transactionReceipt.contractAddress).toBeTruthy(); - - contractAddress = deployOut.transactionReceipt.contractAddress as string; - expect(typeof contractAddress).toBeString(); - - const { callOutput: helloMsg } = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }); - expect(helloMsg).toBeTruthy(); - expect(typeof helloMsg).toBeString(); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async () => { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - }); - expect(setNameOut).toBeTruthy(); - - try { - await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - }); - fail( - "PluginLedgerConnectorEthereum.invokeContract failed to throw error", - ); - } catch (error) { - expect(error).not.toBe("Nonce too low"); - } - - const getNameOut = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }); - expect(getNameOut.success).toBeTruthy(); - - const { callOutput: getNameOut2 } = await connector.getContractInfoKeychain( - { - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }, - ); - expect(getNameOut2).toEqual(newName); - }); - - test("invoke Web3SigningCredentialType.NONE", async () => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - expect(balance2).toBeTruthy(); - expect(balance2.toString()).toEqual(value.toString()); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async () => { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - }); - expect(setNameOut).toBeTruthy(); - - try { - await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - }); - fail( - "PluginLedgerConnectorEthereum.invokeContract failed to throw error", - ); - } catch (error) { - expect(error).not.toBe("Nonce too low"); - } - const { callOutput: getNameOut } = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - }); - expect(getNameOut).toEqual(newName); - - const getNameOut2 = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - }); - expect(getNameOut2).toBeTruthy(); - }); - - test("invoke Web3SigningCredentialType.CactusKeychainRef", async () => { - const newName = `DrCactus${uuidV4()}`; - - const web3SigningCredential: Web3SigningCredentialCactusKeychainRef = { - ethAccount: testEthAccount.address, - keychainEntryKey, - keychainId: keychainPlugin.getKeychainId(), - type: Web3SigningCredentialType.CactusKeychainRef, - }; - - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential, - nonce: 3, - }); - expect(setNameOut).toBeTruthy(); - - try { - await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 3, - }); - fail( - "PluginLedgerConnectorEthereum.invokeContract failed to throw error", - ); - } catch (error) { - expect(error).not.toBe("Nonce too low"); - } - const { callOutput: getNameOut } = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential, - }); - expect(getNameOut).toEqual(newName); - - const getNameOut2 = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential, - }); - expect(getNameOut2).toBeTruthy(); - }); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract-json-object-endpoints.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract-json-object-endpoints.test.ts deleted file mode 100644 index 8cddba7428..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract-json-object-endpoints.test.ts +++ /dev/null @@ -1,362 +0,0 @@ -import test, { Test } from "tape"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { - LogLevelDesc, - IListenOptions, - Servers, -} from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../solidity/hello-world-contract/HelloWorld.json"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, - DefaultApi as EthereumApi, -} from "../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; -import { Configuration, Constants } from "@hyperledger/cactus-core-api"; -import { Server as SocketIoServer } from "socket.io"; - -import express from "express"; -import bodyParser from "body-parser"; -import http from "http"; -import { AddressInfo } from "net"; - -const logLevel: LogLevelDesc = "INFO"; - -test("Ethereum Ledger Connector Plugin", async (t: Test) => { - const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "localhost", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; - t.comment( - `Metrics URL: ${apiHost}/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-ethereum/get-prometheus-exporter-metrics`, - ); - - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new EthereumApi(apiConfig); - - const wsApi = new SocketIoServer(server, { - path: Constants.SocketIoConnectionPathV1, - }); - - await connector.getOrCreateWebServices(); - await connector.registerWebServices(expressApp, wsApi); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - t.ok(balance, "Retrieved balance of test account OK"); - t.equals( - balance.toString(), - initTransferValue, - "Balance of test account is OK", - ); - - let contractAddress: string; - - test("deploys contract via .json file", async (t2: Test) => { - const deployOut = await apiClient.deployContractSolBytecodeJsonObjectV1({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(deployOut, "deployContract() output is truthy OK"); - t2.ok( - deployOut.data.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t2.ok( - deployOut.data.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - - contractAddress = deployOut.data.transactionReceipt - .contractAddress as string; - t2.ok( - typeof contractAddress === "string", - "contractAddress typeof string OK", - ); - - const helloMsg = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(helloMsg.data.callOutput, "sayHello() output is truthy"); - t2.true( - typeof helloMsg.data.callOutput === "string", - "sayHello() output is type of string", - ); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount( - firstHighNetWorthAccount, - ); - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut.data, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.data.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok( - getNameOut.data.success, - `getName() SEND invocation produced receipt OK`, - ); - - const getNameOut2 = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut2.data.callOutput, - newName, - "setName() invocation #2 output is truthy OK", - ); - - t2.end(); - }); - - test("invoke Web3SigningCredentialType.NONE", async (t2: Test) => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - t2.ok(balance2, "Retrieved balance of test account 2 OK"); - t2.equals( - balance2.toString(), - value.toString(), - "Balance of test account2 is OK", - ); - t2.end(); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount(testEthAccount.address); - const setNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut.data, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.data.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - const getNameOut = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut.data.callOutput, - newName, - `getName() output reflects the update OK`, - ); - - const getNameOut2 = await apiClient.invokeContractV1NoKeychain({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut2.data, "getName() invocation #2 output is truthy OK"); - - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract-json-object.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract-json-object.test.ts deleted file mode 100644 index 3f386e3a7e..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract-json-object.test.ts +++ /dev/null @@ -1,316 +0,0 @@ -import test, { Test } from "tape"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { LogLevelDesc } from "@hyperledger/cactus-common"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialType, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; - -const logLevel: LogLevelDesc = "INFO"; - -test("Ethereum Ledger Connector Plugin", async (t: Test) => { - const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - }); - await ledger.start(); - - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - t.ok(ethereumGenesisOptions); - t.ok(ethereumGenesisOptions.alloc); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry(), - }, - ); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - t.ok(balance, "Retrieved balance of test account OK"); - t.equals( - balance.toString(), - initTransferValue, - "Balance of test account is OK", - ); - - let contractAddress: string; - - test("deploys contract via .json file", async (t2: Test) => { - const deployOut = await connector.deployContractJsonObject({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - contractJSON: HelloWorldContractJson, - }); - t2.ok(deployOut, "deployContract() output is truthy OK"); - t2.ok( - deployOut.transactionReceipt, - "deployContract() output.transactionReceipt is truthy OK", - ); - t2.ok( - deployOut.transactionReceipt.contractAddress, - "deployContract() output.transactionReceipt.contractAddress is truthy OK", - ); - - contractAddress = deployOut.transactionReceipt.contractAddress as string; - t2.ok( - typeof contractAddress === "string", - "contractAddress typeof string OK", - ); - - const { callOutput: helloMsg } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(helloMsg, "sayHello() output is truthy"); - t2.true( - typeof helloMsg === "string", - "sayHello() output is type of string", - ); - }); - - test("invoke Web3SigningCredentialType.GETHKEYCHAINPASSWORD", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount( - firstHighNetWorthAccount, - ); - const setNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - - const getNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut.success, `getName() SEND invocation produced receipt OK`); - - const { callOutput: getNameOut2 } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal( - getNameOut2, - newName, - "setName() invocation #2 output is truthy OK", - ); - - t2.end(); - }); - - test("invoke Web3SigningCredentialType.NONE", async (t2: Test) => { - const testEthAccount2 = web3.eth.accounts.create(); - - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - t2.ok(balance2, "Retrieved balance of test account 2 OK"); - t2.equals( - balance2.toString(), - value.toString(), - "Balance of test account2 is OK", - ); - t2.end(); - }); - - test("invoke Web3SigningCredentialType.PrivateKeyHex", async (t2: Test) => { - const newName = `DrCactus${uuidV4()}`; - const txCount = await web3.eth.getTransactionCount(testEthAccount.address); - const setNameOut = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: Number(txCount), - contractJSON: HelloWorldContractJson, - }); - t2.ok(setNameOut, "setName() invocation #1 output is truthy OK"); - - try { - const setNameOutInvalid = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - contractJSON: HelloWorldContractJson, - }); - t2.ifError(setNameOutInvalid.transactionReceipt); - } catch (error) { - t2.notStrictEqual( - error, - "Nonce too low", - "setName() invocation with invalid nonce", - ); - } - const { callOutput: getNameOut } = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.equal(getNameOut, newName, `getName() output reflects the update OK`); - - const getNameOut2 = await connector.getContractInfo({ - contractAddress, - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - contractJSON: HelloWorldContractJson, - }); - t2.ok(getNameOut2, "getName() invocation #2 output is truthy OK"); - - t2.end(); - }); - - t.end(); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract.test.ts b/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract.test.ts deleted file mode 100644 index cdebb3f4e7..0000000000 --- a/packages/cactus-plugin-ledger-connector-ethereum/src/test/typescript/integration/v21.4.1-invoke-contract.test.ts +++ /dev/null @@ -1,367 +0,0 @@ -import "jest-extended"; -import Web3 from "web3"; -import { v4 as uuidV4 } from "uuid"; - -import { LogLevelDesc } from "@hyperledger/cactus-common"; - -import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; - -import HelloWorldContractJson from "../../../../solidity/hello-world-contract/HelloWorld.json"; - -import { - EthContractInvocationType, - PluginLedgerConnectorEthereum, - Web3SigningCredentialCactusKeychainRef, - Web3SigningCredentialType, -} from "../../../../../main/typescript/public-api"; - -import { - QuorumTestLedger, - IQuorumGenesisOptions, - IAccount, -} from "@hyperledger/cactus-test-tooling"; -import { PluginRegistry } from "@hyperledger/cactus-core"; - -const logLevel: LogLevelDesc = "INFO"; -const contractName = "HelloWorld"; -const testCase = "Ethereum Ledger Connector Plugin"; - -describe(testCase, () => { - afterAll(async () => { - await ledger.stop(); - await ledger.destroy(); - }); - - const containerImageVersion = "2021-05-03-quorum-v21.4.1"; - const ledgerOptions = { containerImageVersion }; - const ledger = new QuorumTestLedger(ledgerOptions); - - test(testCase, async () => { - await ledger.start(); - const rpcApiHttpHost = await ledger.getRpcApiHttpHost(); - const ethereumGenesisOptions: IQuorumGenesisOptions = await ledger.getGenesisJsObject(); - expect(ethereumGenesisOptions).toBeTruthy(); - expect(ethereumGenesisOptions.alloc).toBeTruthy(); - - const highNetWorthAccounts: string[] = Object.keys( - ethereumGenesisOptions.alloc, - ).filter((address: string) => { - const anAccount: IAccount = ethereumGenesisOptions.alloc[address]; - const theBalance = parseInt(anAccount.balance, 10); - return theBalance > 10e7; - }); - const [firstHighNetWorthAccount] = highNetWorthAccounts; - - const web3 = new Web3(rpcApiHttpHost); - const testEthAccount = web3.eth.accounts.create(); - - const keychainEntryKey = uuidV4(); - const keychainEntryValue = testEthAccount.privateKey; - const keychainPlugin = new PluginKeychainMemory({ - instanceId: uuidV4(), - keychainId: uuidV4(), - // pre-provision keychain with mock backend holding the private key of the - // test account that we'll reference while sending requests with the - // signing credential pointing to this keychain entry. - backend: new Map([[keychainEntryKey, keychainEntryValue]]), - logLevel, - }); - keychainPlugin.set( - HelloWorldContractJson.contractName, - JSON.stringify(HelloWorldContractJson), - ); - // Instantiate connector with the keychain plugin that already has the - // private key we want to use for one of our tests - const connector: PluginLedgerConnectorEthereum = new PluginLedgerConnectorEthereum( - { - instanceId: uuidV4(), - rpcApiHttpHost, - logLevel, - pluginRegistry: new PluginRegistry({ plugins: [keychainPlugin] }), - }, - ); - - const initTransferValue = (10e9).toString(); - await connector.transact({ - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - transactionConfig: { - from: firstHighNetWorthAccount, - to: testEthAccount.address, - value: initTransferValue, - }, - }); - - const balance = await web3.eth.getBalance(testEthAccount.address); - expect(balance).toBeTruthy(); - expect(balance.toString()).toEqual(initTransferValue); - let contractAddress: string; - - { - const deployOut = await connector.deployContract({ - keychainId: keychainPlugin.getKeychainId(), - contractName: HelloWorldContractJson.contractName, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - gas: 1000000, - }); - expect(deployOut).toBeTruthy(); - expect(deployOut.transactionReceipt).toBeTruthy(); - expect(deployOut.transactionReceipt.contractAddress).toBeTruthy(); - - contractAddress = deployOut.transactionReceipt.contractAddress as string; - expect(typeof contractAddress === "string").toBeTrue(); - - const { callOutput: helloMsg } = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Call, - methodName: "sayHello", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }); - expect(helloMsg).toBeTruthy(); - expect(typeof helloMsg === "string").toBeTrue(); - } - - { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - }); - expect(setNameOut).toBeTruthy(); - - try { - const setNameOutInvalid = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 2, - }); - expect(setNameOutInvalid.transactionReceipt).toBeFalsy(); - } catch (error) { - expect(error.message).toMatch(/nonce too low/); - } - - const getNameOut = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }); - expect(getNameOut.success).toBeTruthy(); - - const { - callOutput: getNameOut2, - } = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - }); - expect(getNameOut2).toEqual(newName); - } - - { - const testEthAccount2 = web3.eth.accounts.create(); - const value = 10e6; - const { rawTransaction } = await web3.eth.accounts.signTransaction( - { - from: testEthAccount.address, - to: testEthAccount2.address, - value, - gas: 1000000, - }, - testEthAccount.privateKey, - ); - - await connector.transact({ - web3SigningCredential: { - type: Web3SigningCredentialType.None, - }, - transactionConfig: { - rawTransaction, - }, - }); - - const balance2 = await web3.eth.getBalance(testEthAccount2.address); - expect(balance2).toBeTruthy(); - expect(balance2.toString()).toEqual(value.toString()); - } - - { - const newName = `DrCactus${uuidV4()}`; - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - }); - expect(setNameOut).toBeTruthy(); - - try { - const setNameOutInvalid = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - nonce: 1, - }); - expect(setNameOutInvalid.transactionReceipt).toBeFalsy(); - } catch (error) { - expect(error.message).toMatch(/nonce too low/); - } - const { - callOutput: getNameOut, - } = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - }); - expect(getNameOut).toEqual(newName); - - const getNameOut2 = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential: { - ethAccount: testEthAccount.address, - secret: testEthAccount.privateKey, - type: Web3SigningCredentialType.PrivateKeyHex, - }, - }); - expect(getNameOut2).toBeTruthy(); - } - - { - const newName = `DrCactus${uuidV4()}`; - - const web3SigningCredential: Web3SigningCredentialCactusKeychainRef = { - ethAccount: testEthAccount.address, - keychainEntryKey, - keychainId: keychainPlugin.getKeychainId(), - type: Web3SigningCredentialType.CactusKeychainRef, - }; - - const setNameOut = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential, - nonce: 3, - }); - expect(setNameOut).toBeTruthy(); - - try { - const setNameOutInvalid = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "setName", - params: [newName], - gas: 1000000, - web3SigningCredential: { - ethAccount: firstHighNetWorthAccount, - secret: "", - type: Web3SigningCredentialType.GethKeychainPassword, - }, - nonce: 3, - }); - expect(setNameOutInvalid.transactionReceipt).toBeFalsy(); - } catch (error) { - expect(error.message).toMatch(/nonce too low/); - } - const { - callOutput: getNameOut, - } = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Call, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential, - }); - expect(getNameOut).toEqual(newName); - - const getNameOut2 = await connector.getContractInfoKeychain({ - contractName, - keychainId: keychainPlugin.getKeychainId(), - invocationType: EthContractInvocationType.Send, - methodName: "getName", - params: [], - gas: 1000000, - web3SigningCredential, - }); - expect(getNameOut2).toBeTruthy(); - } - }); -}); diff --git a/packages/cactus-plugin-ledger-connector-ethereum/tsconfig.json b/packages/cactus-plugin-ledger-connector-ethereum/tsconfig.json index 4de83347e8..d5d32e83ec 100644 --- a/packages/cactus-plugin-ledger-connector-ethereum/tsconfig.json +++ b/packages/cactus-plugin-ledger-connector-ethereum/tsconfig.json @@ -9,7 +9,7 @@ "tsBuildInfoFile": "../../.build-cache/cactus-plugin-ledger-connector-ethereum.tsbuildinfo" }, "include": [ - "./src/main", + "./src/", "src/**/*.json" ], "references": [ diff --git a/packages/cactus-test-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/deploy-contract-via-web-service.test.ts b/packages/cactus-test-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/deploy-contract-via-web-service.test.ts index 120749cbb6..bd75a1e34a 100644 --- a/packages/cactus-test-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/deploy-contract-via-web-service.test.ts +++ b/packages/cactus-test-plugin-ledger-connector-ethereum/src/test/typescript/integration/plugin-ledger-connector-ethereum/deploy-contract/deploy-contract-via-web-service.test.ts @@ -216,7 +216,7 @@ describe(testCase, () => { invocationType: EthContractInvocationType.Send, methodName: "setName", params: [newName], - gas: 1000000, + gas: "1000000", web3SigningCredential: { ethAccount: testEthAccount.address, secret: testEthAccount.privateKey, @@ -234,7 +234,7 @@ describe(testCase, () => { invocationType: EthContractInvocationType.Call, methodName: "getName", params: [], - gas: 1000000, + gas: "1000000", web3SigningCredential: { ethAccount: testEthAccount.address, secret: testEthAccount.privateKey, @@ -254,7 +254,7 @@ describe(testCase, () => { invocationType: EthContractInvocationType.Send, methodName: "getName", params: [], - gas: 1000000, + gas: "1000000", web3SigningCredential: { ethAccount: testEthAccount.address, secret: testEthAccount.privateKey, diff --git a/yarn.lock b/yarn.lock index 442440f415..e640bf7e2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31149,6 +31149,21 @@ web3-core@4.0.3-dev.602dada.0+602dada: optionalDependencies: web3-providers-ipc "4.0.3-dev.602dada.0+602dada" +web3-core@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-4.0.3.tgz#eab6cc23a43ff202d8f38bbd9801a7a2ec750cc2" + integrity sha512-KJaH1+ajm/gelvhImkXZx8HrBaGZDERqhOCRpikuwReVDTf4X3TlXqF+oKt153qf5HUXWR4CUL6NkNKNQWjhbA== + dependencies: + web3-errors "^1.0.2" + web3-eth-iban "^4.0.3" + web3-providers-http "^4.0.3" + web3-providers-ws "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + optionalDependencies: + web3-providers-ipc "^4.0.3" + web3-errors@1.0.2-dev.602dada.0+602dada: version "1.0.2-dev.602dada.0" resolved "https://registry.yarnpkg.com/web3-errors/-/web3-errors-1.0.2-dev.602dada.0.tgz#614e02b847e454943730a871a8de271dcd86e555" @@ -31156,6 +31171,13 @@ web3-errors@1.0.2-dev.602dada.0+602dada: dependencies: web3-types "1.0.2-dev.602dada.0+602dada" +web3-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-errors/-/web3-errors-1.0.2.tgz#e8ce6e22dfdfd9aeaf8d7535653e55b094b5accd" + integrity sha512-LtRUASAQKeCKyxHRhfyU5xiE9asUmo7KJ9bEzzaPlkVYLl5lzhUXzd6lvnQfSaSXJnlzoUXvhI5I0Hpzc8Lohg== + dependencies: + web3-types "^1.0.2" + web3-eth-abi@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.0.tgz#53a7a2c95a571e205e27fd9e664df4919483cce1" @@ -31215,6 +31237,17 @@ web3-eth-abi@4.0.3-dev.602dada.0+602dada: web3-types "1.0.2-dev.602dada.0+602dada" web3-utils "4.0.3-dev.602dada.0+602dada" +web3-eth-abi@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-4.0.3.tgz#cc06cc39868d8bcc181528aa46ae9d5c80ed93b6" + integrity sha512-is1sKkTna5LQri25iRbxJ43kQ6qlFR/Syi6dnpwsFua0qAyKuDTxLZDoMaBfdH8NvxvjuGWFUWALwuSk8gk5Xg== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-eth-accounts@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.0.tgz#2942beca0a4291455f32cf09de10457a19a48117" @@ -31316,7 +31349,20 @@ web3-eth-accounts@1.8.1: web3-core-method "1.8.1" web3-utils "1.8.1" -web3-eth-accounts@4.0.3-dev.602dada.0, web3-eth-accounts@4.0.3-dev.602dada.0+602dada, web3-eth-accounts@dev: +web3-eth-accounts@4.0.3, web3-eth-accounts@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-4.0.3.tgz#7e570b3170aca052b358975235637a94b5313826" + integrity sha512-qS4r25weJYlKzHPIneL3g33LG+I6QkRCs25ZtooK6elurlZY4HyRE04BIWv12xZswtsvdmMt4HysMUNKgLrgPg== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + crc-32 "^1.2.2" + ethereum-cryptography "^2.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-accounts@4.0.3-dev.602dada.0+602dada, web3-eth-accounts@dev: version "4.0.3-dev.602dada.0" resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-4.0.3-dev.602dada.0.tgz#36545713652e719a931c1b2dba9a13a41ba57380" integrity sha512-Sqf5gSxbkm5zbSirs+qk+bti0oc2192DeQAUzTQzT1YtwvSqCA8ntPG1Nrtz2Va2GeyIT+/TkmUna2uWMtYukw== @@ -31413,7 +31459,20 @@ web3-eth-contract@1.8.1: web3-eth-abi "1.8.1" web3-utils "1.8.1" -web3-eth-contract@4.0.3-dev.602dada.0, web3-eth-contract@4.0.3-dev.602dada.0+602dada: +web3-eth-contract@4.0.3, web3-eth-contract@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-4.0.3.tgz#667e8f8052034f49a9130e0f286976bcf43c5d77" + integrity sha512-x8YsIVVUeONwLCnUmswk5KD3luYxaKuN/xnSzxpb8fE4/KBA6eJswYcIGPrK9QILrVR26yDV/QQpgLU1IJS14g== + dependencies: + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-abi "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-contract@4.0.3-dev.602dada.0+602dada: version "4.0.3-dev.602dada.0" resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-4.0.3-dev.602dada.0.tgz#d76ecb9beb9ed33b13648df763c80186ac7a9d23" integrity sha512-nTVgYQBSpSru/o4JIIANXLwEwC9vjz7QUIrDUivSnC5Xsp7PU+453FAvZDwdzF+Cqsq4o3BkfxVu+y3UNW2E8w== @@ -31525,6 +31584,21 @@ web3-eth-ens@4.0.3-dev.602dada.0+602dada: web3-utils "4.0.3-dev.602dada.0+602dada" web3-validator "1.0.2-dev.602dada.0+602dada" +web3-eth-ens@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-4.0.3.tgz#9b17bdcdc262ddcb5b9fd0b4893c0a9a56bf07ca" + integrity sha512-1tk1WWJB6lsViRFxHR9kt8qgfMV0cySeNBa8H/bZ9/HZ1G8L/c2cboVrG4D0QsPO1im1jQl4Cf3ceKH0PW1KZg== + dependencies: + "@adraffy/ens-normalize" "^1.8.8" + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-contract "^4.0.3" + web3-net "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + web3-eth-iban@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.0.tgz#5a46646401965b0f09a4f58e7248c8a8cd22538a" @@ -31583,6 +31657,16 @@ web3-eth-iban@4.0.3-dev.602dada.0+602dada: web3-utils "4.0.3-dev.602dada.0+602dada" web3-validator "1.0.2-dev.602dada.0+602dada" +web3-eth-iban@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-4.0.3.tgz#3fca87323c00a29f1b3870d397153803eb0bcf4e" + integrity sha512-9gn6fb034fh3DvQeutuhaG3J9+ZSriPC/O/H7K+lgUWJZh/lpaZy5A06nhHzNcleCWC07Q6J7d7VZlNjaBPtOA== + dependencies: + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + web3-eth-personal@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.0.tgz#94d525f7a29050a0c2a12032df150ac5ea633071" @@ -31667,6 +31751,18 @@ web3-eth-personal@4.0.3-dev.602dada.0+602dada: web3-utils "4.0.3-dev.602dada.0+602dada" web3-validator "1.0.2-dev.602dada.0+602dada" +web3-eth-personal@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-4.0.3.tgz#df4c59bf2a0e07cd6966259d1312be6b5b61846e" + integrity sha512-Gugz45w/D4wlUNbUth8iHWkv0c5fFZGWZqFvpACJul0z9h0Ou8HzuJMUv3U0xFOQJF5fniVegfp6l0FJQ3hGrQ== + dependencies: + web3-core "^4.0.3" + web3-eth "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + web3-eth@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.0.tgz#38b905e2759697c9624ab080cfcf4e6c60b3a6cf" @@ -31775,7 +31871,24 @@ web3-eth@1.8.1: web3-net "1.8.1" web3-utils "1.8.1" -web3-eth@4.0.3-dev.602dada.0, web3-eth@4.0.3-dev.602dada.0+602dada: +web3-eth@4.0.3, web3-eth@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-4.0.3.tgz#b7f311eba95151f547ccce285893af9917da9e35" + integrity sha512-4t1+lpqzk3ljubr0CKE9Ila82p2Pim6Bn7ZIruVfMt9AOA5wL6M0OeMTy0fWBODLJiZJ7R77Ugm0kvEVWD3lqg== + dependencies: + setimmediate "^1.0.5" + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth-abi "^4.0.3" + web3-eth-accounts "^4.0.3" + web3-net "^4.0.3" + web3-providers-ws "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth@4.0.3-dev.602dada.0+602dada: version "4.0.3-dev.602dada.0" resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-4.0.3-dev.602dada.0.tgz#64b25051e7886db99b1b55aa4f822db9baf182bd" integrity sha512-YDQNpM16c/h6y8AowcC9+N8Mq+MqWJMaFqADf1apj84WZMtc8sypWj/evU46NzQg995h4Sxs8p7vTFLHVeDWfw== @@ -31856,6 +31969,16 @@ web3-net@4.0.3-dev.602dada.0+602dada: web3-types "1.0.2-dev.602dada.0+602dada" web3-utils "4.0.3-dev.602dada.0+602dada" +web3-net@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-4.0.3.tgz#9aeed6fa3d48adcf63d8377900acbe3e64020154" + integrity sha512-qe+stvVgYhO8AiPgDykZW5gS4mZ3GRWdQ8xn3eTvderresIMvdZYSAoUla2jWl1CgpcqzaoOSO9Pf8t43fr8SA== + dependencies: + web3-core "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-providers-http@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.0.tgz#864fa48675e7918c9a4374e5f664b32c09d0151b" @@ -31918,6 +32041,16 @@ web3-providers-http@4.0.3-dev.602dada.0+602dada: web3-types "1.0.2-dev.602dada.0+602dada" web3-utils "4.0.3-dev.602dada.0+602dada" +web3-providers-http@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-4.0.3.tgz#c6c8364ed56c4183e6bed58de20c1972f513c7ae" + integrity sha512-5E6nKjWrwlJdhGImOxyTnFDT6UcZu4waO6AJrENBRh2vdoCfP/Piiv3PLywHs71gwTMsAjy6CNPL5lZdGf+JQA== + dependencies: + cross-fetch "^3.1.5" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-providers-ipc@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.0.tgz#9747c7a6aee96a51488e32fa7c636c3460b39889" @@ -31975,6 +32108,15 @@ web3-providers-ipc@4.0.3-dev.602dada.0+602dada: web3-types "1.0.2-dev.602dada.0+602dada" web3-utils "4.0.3-dev.602dada.0+602dada" +web3-providers-ipc@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-4.0.3.tgz#d7af699a2afae0f7396d08ef8cc82b5ab4374398" + integrity sha512-v+Ugp5XXUVcAQju/u4ThdjI3FM9lq674F6cJ7yz3R6uTel+wNPDiT47Se8hvm5grgHid7z3MbVYCQpDCiiAFHw== + dependencies: + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-providers-ws@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.0.tgz#cb0b87b94c4df965cdf486af3a8cd26daf3975e5" @@ -32041,6 +32183,18 @@ web3-providers-ws@4.0.3-dev.602dada.0+602dada: web3-utils "4.0.3-dev.602dada.0+602dada" ws "^8.8.1" +web3-providers-ws@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-4.0.3.tgz#c611a0ae81ac022d8ccb01f71da761f7b4decd85" + integrity sha512-V2bYiMvhv+xBYxFdf8V1zGTwhJoAkBQNMECVGNjQIz1qBKuqu6hXHasmkYSJV780LD6qoL58KlfTggjf4SUSaA== + dependencies: + "@types/ws" "^8.5.3" + isomorphic-ws "^5.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + ws "^8.8.1" + web3-rpc-methods@1.0.2-dev.602dada.0+602dada: version "1.0.2-dev.602dada.0" resolved "https://registry.yarnpkg.com/web3-rpc-methods/-/web3-rpc-methods-1.0.2-dev.602dada.0.tgz#fa3d6ff4500216d2835f931e51319c6aa4e607d9" @@ -32050,6 +32204,15 @@ web3-rpc-methods@1.0.2-dev.602dada.0+602dada: web3-types "1.0.2-dev.602dada.0+602dada" web3-validator "1.0.2-dev.602dada.0+602dada" +web3-rpc-methods@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-rpc-methods/-/web3-rpc-methods-1.0.2.tgz#3ff35c5d4e38ad31ef3cf77eb3fe2fd08e2a3f4a" + integrity sha512-VhLHvgR62JUNgo0op8hP4LcRkvdF0WaHD9xhcEKGLcri9VfYvR1yTZ3CVh6NTgRCmfDePObbp5blHfbla1cC5Q== + dependencies: + web3-core "^4.0.3" + web3-types "^1.0.2" + web3-validator "^1.0.2" + web3-shh@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.0.tgz#c2979b87e0f67a7fef2ce9ee853bd7bfbe9b79a8" @@ -32115,6 +32278,11 @@ web3-types@1.0.2-dev.602dada.0+602dada: resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.0.2-dev.602dada.0.tgz#b29515b71893f272954c6fde30727583da148d2b" integrity sha512-L4Rp0Ocmf/N0oz0ibX8Wn8RIQcuaMBb1+KEveGvuEMBqmAA74tCgYU+X4NP4KJbaE0sq1Cm74vyLmRlxpz4PtQ== +web3-types@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.0.2.tgz#1655a400d31984153fc26ca1f8960f547ca1f2df" + integrity sha512-tLzA9vevGGWdHlxXvPRJjEIIR0UnZBI5Kq9qiENRS/vSekTHAHp7u+WGDxt+6kP105gKlbep50TogQIvJqLfnA== + web3-utils@1.10.0, web3-utils@^1.0.0-beta.31: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.0.tgz#ca4c1b431a765c14ac7f773e92e0fd9377ccf578" @@ -32193,7 +32361,17 @@ web3-utils@1.8.1: randombytes "^2.1.0" utf8 "3.0.0" -web3-utils@4.0.3-dev.602dada.0, web3-utils@4.0.3-dev.602dada.0+602dada: +web3-utils@4.0.3, web3-utils@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-4.0.3.tgz#80c077e56c0841528ea4513c67d83e460217b379" + integrity sha512-clBvm/vWR2mAc9nPnsPYBZMikIhVG9RAsXdrxvXI4e2jAQ3DTtHKMhqy+Cl214dQaAdAEYyVb5ILW5lKKqk2vA== + dependencies: + ethereum-cryptography "^2.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-validator "^1.0.2" + +web3-utils@4.0.3-dev.602dada.0+602dada: version "4.0.3-dev.602dada.0" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-4.0.3-dev.602dada.0.tgz#21b043b48062ccdfd738786c86c271457441378b" integrity sha512-eJoq2qXlCTK5DBq1paxtpVe9Ti+348K/lExfR/VVCbvQ77GJXhhir0OmXpy7JciSqUlbPu673PL9kBt09daHNA== @@ -32214,6 +32392,17 @@ web3-validator@1.0.2-dev.602dada.0+602dada: web3-errors "1.0.2-dev.602dada.0+602dada" web3-types "1.0.2-dev.602dada.0+602dada" +web3-validator@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-validator/-/web3-validator-1.0.2.tgz#ca7d247b49f4f690db86e5b953272a627dc5950a" + integrity sha512-orx1CQAEnwJUnl/8iF2II2zSA4wiooNJvFmVE0Dbmt/kE370SugIDViQP76snhxtouG2AXzz4GyKbPCMlLGh/A== + dependencies: + ethereum-cryptography "^2.0.0" + is-my-json-valid "^2.20.6" + util "^0.12.5" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.0.tgz#2fde0009f59aa756c93e07ea2a7f3ab971091274" @@ -32292,7 +32481,29 @@ web3@1.8.1: web3-shh "1.8.1" web3-utils "1.8.1" -web3@4.0.3-dev.602dada.0, web3@dev: +web3@4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3/-/web3-4.0.3.tgz#afeb977c9f883ff683d630ab9f5937eb56bc7cf4" + integrity sha512-rUMxui5f52yPWjiMRQV6xqIrTQSovYM2CNhl57y+xj/fGXNLbI1D5FsLPnUMZjMaFHJBTteaBxq/sTEaw/1jNA== + dependencies: + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-abi "^4.0.3" + web3-eth-accounts "^4.0.3" + web3-eth-contract "^4.0.3" + web3-eth-ens "^4.0.3" + web3-eth-iban "^4.0.3" + web3-eth-personal "^4.0.3" + web3-net "^4.0.3" + web3-providers-http "^4.0.3" + web3-providers-ws "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3@dev: version "4.0.3-dev.602dada.0" resolved "https://registry.yarnpkg.com/web3/-/web3-4.0.3-dev.602dada.0.tgz#25ac1b1b156f156cb8e159e6d9a81d478803d6e2" integrity sha512-5ZLkMHL7K0j22iD9Z8Uz0KAifEaIyrR8glh2CR7we/xjuPHt5yJI9+FS4aTdaWw++NcpdrMPeG+ss3dzLDJVaQ==