diff --git a/components/overledger/actions/execute-signed-transaction/execute-signed-transaction.mjs b/components/overledger/actions/execute-signed-transaction/execute-signed-transaction.mjs index 66b9082f38218..6dde413c438be 100644 --- a/components/overledger/actions/execute-signed-transaction/execute-signed-transaction.mjs +++ b/components/overledger/actions/execute-signed-transaction/execute-signed-transaction.mjs @@ -4,29 +4,39 @@ export default { key: "overledger-execute-signed-transaction", name: "Execute Signed Transaction", description: "Executes a signed transaction by sending it to a blockchain node via Overledger. [See the documentation](https://developers.quant.network/reference/executesignedrequest)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { overledger, + environment: { + propDefinition: [ + overledger, + "environment", + ], + }, requestId: { type: "string", label: "Request ID", - description: "The ID of the request for executing a signed transaction.", + description: "The Overledger identifier assigned to the related transaction preparation request. This should be set to the requestId parameter found in the response object of the 'Prepare a Smart Contract Transaction' Overledger action.", }, signedTransaction: { type: "string", label: "Signed Transaction", - description: "The signed transaction data.", + description: "The raw transaction bytecode after signing. This should be set to the signed parameter found in the response object of the 'Sign a Transaction' Overledger action.", optional: true, }, }, async run({ $ }) { + + const requestBody = { + requestId: this.requestId, + signedTransaction: this.signedTransaction, + }; + const response = await this.overledger.executeSignedTransaction({ $, - data: { - requestId: this.requestId, - signedTransaction: this.signedTransaction, - }, + environment: this.environment, + data: requestBody, }); $.export("$summary", `Successfully executed signed transaction with Request ID ${this.requestId}`); diff --git a/components/overledger/actions/prepare-smart-contract-transaction/prepare-smart-contract-transaction.mjs b/components/overledger/actions/prepare-smart-contract-transaction/prepare-smart-contract-transaction.mjs index 8a07e23324403..deb49aa89a537 100644 --- a/components/overledger/actions/prepare-smart-contract-transaction/prepare-smart-contract-transaction.mjs +++ b/components/overledger/actions/prepare-smart-contract-transaction/prepare-smart-contract-transaction.mjs @@ -8,10 +8,16 @@ export default { key: "overledger-prepare-smart-contract-transaction", name: "Prepare Smart Contract Transaction", description: "Prepares a smart contract transaction for signing on the Overledger platform. [See the documentation](https://developers.quant.network/reference/preparesmartcontractwrite)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { overledger, + environment: { + propDefinition: [ + overledger, + "environment", + ], + }, locationTechnology: { type: "string", label: "Location Technology", @@ -22,19 +28,19 @@ export default { signingAccountId: { type: "string", label: "Signing Account ID", - description: "The blockchain account that will sign the transaction.", + description: "The blockchain account (address) that you will be sending this transaction", + }, + smartContractId: { + type: "string", + label: "Smart Contract ID", + description: "The ID/address of the smart contract to interact with.", + }, functionName: { type: "string", label: "Function Name", description: "The name of the function to call on the smart contract.", }, - smartContractId: { - propDefinition: [ - overledger, - "smartContractId", - ], - }, inputParameters: { type: "string[]", label: "Input Parameters", @@ -55,18 +61,21 @@ export default { return props; }, async run({ $ }) { + const requestBody = { + location: { + technology: this.locationTechnology, + network: this.locationNetwork, + }, + signingAccountId: this.signingAccountId, + functionName: this.functionName, + smartContractId: this.smartContractId, + inputParameters: parseObject(this.inputParameters), //parse these values using the parseObject function at this shouls turn the JSON string into JSON objects to used in the request body. + }; + const response = await this.overledger.prepareSmartContractTransaction({ $, - data: { - location: { - technology: this.locationTechnology, - network: this.locationNetwork, - }, - signingAccountId: this.signingAccountId, - functionName: this.functionName, - smartContractId: this.smartContractId, - inputParameters: this.inputParameters && parseObject(this.inputParameters), - }, + environment: this.environment, + data: requestBody, }); $.export("$summary", "Smart contract transaction prepared successfully"); return response; diff --git a/components/overledger/actions/read-from-a-smart-contract/read-from-a-smart-contract.mjs b/components/overledger/actions/read-from-a-smart-contract/read-from-a-smart-contract.mjs new file mode 100644 index 0000000000000..7898ad5c8b216 --- /dev/null +++ b/components/overledger/actions/read-from-a-smart-contract/read-from-a-smart-contract.mjs @@ -0,0 +1,83 @@ +import { + NETWORK_OPTIONS, TECHNOLOGY_OPTIONS, +} from "../../common/constants.mjs"; +import { parseObject } from "../../common/utils.mjs"; +import overledger from "../../overledger.app.mjs"; + +export default { + key: "overledger-read-from-a-smart-contract", + name: "Read from a smart contract", + description: "Reads data from a specified smart contract on the Overledger network.", + version: "0.0.1", + type: "action", + props: { + overledger, + environment: { + propDefinition: [ + overledger, + "environment", + ], + }, + locationTechnology: { + type: "string", + label: "Location Technology", + description: "The technology of the blockchain that the transaction will be submitted to", + options: TECHNOLOGY_OPTIONS, + reloadProps: true, + }, + functionName: { + type: "string", + label: "Function Name", + description: "The name of the function to call on the smart contract.", + }, + inputParameters: { + type: "string[]", + label: "Input Parameters - Stringified Objects", + description: "The input parameters for the smart contract function, in JSON string format. Example: `['{\"type\":\"string\",\"value\":\"param1\"}', '{\"type\":\"uint256\",\"value\":\"param2\"}']`", + optional: true, + }, + smartContractId: { + type: "string", + label: "Smart Contract ID", + description: "The ID/address of the smart contract to interact with.", + }, + outputParameters: { + type: "string[]", + label: "Output Parameters", + description: "The type of output parameter required e.g., address, string", + }, + }, + async additionalProps() { + const props = {}; + if (this.locationTechnology) { + props.locationNetwork = { + type: "string", + label: "Location Network", + description: "The blockchain network the transaction will be submitted to.", + options: NETWORK_OPTIONS[this.locationTechnology], + }; + } + return props; + }, + async run({ $ }) { + + const requestBody = { + location: { + technology: this.locationTechnology, + network: this.locationNetwork, + }, + functionName: this.functionName, + inputParameters: parseObject(this.inputParameters), //parse these values using the parseObject function at this shouls turn the JSON string into JSON objects to used in the request body. + smartContractId: this.smartContractId, + outputParameters: parseObject(this.outputParameters), + }; + // Make the API call to Overledger + const response = await this.overledger.readFromSmartContract({ + $, + environment: this.environment, + data: requestBody, + }); + $.export("$summary", `Successfully read from contract: ${this.smartContractId}`); + return response; + }, +}; diff --git a/components/overledger/actions/sign-a-transaction/sign-a-transaction.mjs b/components/overledger/actions/sign-a-transaction/sign-a-transaction.mjs new file mode 100644 index 0000000000000..af30ce4067766 --- /dev/null +++ b/components/overledger/actions/sign-a-transaction/sign-a-transaction.mjs @@ -0,0 +1,73 @@ +import overledger from "../../overledger.app.mjs"; +import { UNIT_OPTIONS } from "../../common/constants.mjs"; + +export default { + key: "overledger-sign-a-transaction", + name: "Sign a transaction", + description: "Sign a transaction using Overledger", + version: "0.0.1", + type: "action", + props: { + overledger, + environment: { + propDefinition: [ + overledger, + "environment", + ], + }, + locationTechnology: { + type: "string", + label: "Location Technology", + description: "The blockchain technology used for this transaction, e.g., ethereum, substrate - required in order to set the dltfee", + }, + keyId: { + type: "string", + label: "Signing Account ID", + description: "The blockchain account that will sign the transaction.", + }, + requestId: { + type: "string", + label: "requestId", + description: "The ID assigned to a preparation request in Overledger. This should be set to the requestId parameter found in the response object of the 'Prepare Smart Contract Transaction' Overledger action.", + }, + transactionSigningResponderName: { + type: "string", + label: "Transaction Signing Responder Name", + description: "The name of the Transaction Signing Responder you would like to use. The CTA Transaction Signing Responder is the Quant-provided signer for testnet accounts.", + }, + nativeData: { + type: "object", + label: "Native Data", + description: "A JSON object representing the transaction required to be signed.", + }, + }, + async run({ $ }) { + //default values of gatewayFee and dltfee hard coded into params. + const gatewayFee = { + amount: "0", + unit: "QNT", + }; + // Define DLT Fee and dynamically set the 'unit/symbol' from UNIT_OPTIONS + const dltFee = { + amount: "0.000019897764079968", + unit: UNIT_OPTIONS[this.locationTechnology] || "ETH", // Use default if not found + }; + // Sign the transaction + const requestBody = { + keyId: this.keyId, + gatewayFee: gatewayFee, + requestId: this.requestId, + dltFee: dltFee, + nativeData: this.nativeData, + transactionSigningResponderName: this.transactionSigningResponderName, + }; + + const response = await this.overledger.signTransaction({ + $, + environment: this.environment, + data: requestBody, + }); + $.export("$summary", "Transaction signed successfully"); + return response; + }, +}; diff --git a/components/overledger/common/constants.mjs b/components/overledger/common/constants.mjs index 95edbcbf63ac1..e9e8dd4a77959 100644 --- a/components/overledger/common/constants.mjs +++ b/components/overledger/common/constants.mjs @@ -50,3 +50,22 @@ export const NETWORK_OPTIONS = { "Sandbox", ], }; +//Overledger environment to be used - Test or Live +export const OVERLEDGER_INSTANCE = [ + { + label: "Sandbox", + value: "sandbox", + }, + { + label: "Overledger", + value: "overledger", + }, +]; +///unit options to allow for the correct selection based on the location network +export const UNIT_OPTIONS = { + "ethereum": "ETH", // Ethereum's token symbol is ETH + "substrate": "DOT", // Polkadot's token symbol is DOT + "xrp ledger": "XRP", // XRP Ledger's token symbol is XRP + "bitcoin": "BTC", // Bitcoin's token symbol is BTC + "hyperledger fabric": "FAB", // Placeholder for Hyperledger Fabric's token symbol +}; diff --git a/components/overledger/overledger.app.mjs b/components/overledger/overledger.app.mjs index 202f732ae0519..d7f4e561f6569 100644 --- a/components/overledger/overledger.app.mjs +++ b/components/overledger/overledger.app.mjs @@ -1,4 +1,5 @@ import { axios } from "@pipedream/platform"; +import { OVERLEDGER_INSTANCE } from "./common/constants.mjs"; export default { type: "app", @@ -9,11 +10,14 @@ export default { label: "Smart Contract ID", description: "The ID of the smart contract to interact with.", }, + environment: { + type: "string", + label: "Overledger Instance", + description: "Select the Overledger instance to be used", + options: OVERLEDGER_INSTANCE, + }, }, methods: { - _baseUrl() { - return "https://api.overledger.io"; - }, _headers() { return { "Authorization": `Bearer ${this.$auth.oauth_access_token}`, @@ -21,12 +25,17 @@ export default { "API-Version": "3.0.0", }; }, + _getBaseUrl(environment) { //conditional for environment url selection. + return environment === "sandbox" + ? "https://api.sandbox.overledger.io" + : "https://api.overledger.io"; + }, _makeRequest({ - $ = this, path, ...otherOpts + $ = this, environment, path, ...otherOpts }) { return axios($, { ...otherOpts, - url: this._baseUrl() + path, + url: this._getBaseUrl(environment) + path, headers: this._headers(), }); }, @@ -37,6 +46,20 @@ export default { ...opts, }); }, + readFromSmartContract(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/api/smart-contracts/read", + ...opts, + }); + }, + signTransaction(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/api/transaction-signing-sandbox", + ...opts, + }); + }, executeSignedTransaction(opts = {}) { return this._makeRequest({ method: "POST", @@ -54,11 +77,12 @@ export default { }); }, deleteHook({ - path, webhookId, + path, webhookId, ...opts }) { return this._makeRequest({ method: "DELETE", path: `/api/webhooks/${path}/${webhookId}`, + ...opts, }); }, }, diff --git a/components/overledger/package.json b/components/overledger/package.json index 8b691556dba80..7cb7ad307a8bb 100644 --- a/components/overledger/package.json +++ b/components/overledger/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/overledger", - "version": "0.1.0", + "version": "0.2.0", "description": "Pipedream Overledger Components", "main": "overledger.app.mjs", "keywords": [ diff --git a/components/overledger/sources/common/base.mjs b/components/overledger/sources/common/base.mjs index ffce0a02e37f3..c6a6ae816976f 100644 --- a/components/overledger/sources/common/base.mjs +++ b/components/overledger/sources/common/base.mjs @@ -6,6 +6,12 @@ import overledger from "../../overledger.app.mjs"; export default { props: { overledger, + environment: { + propDefinition: [ + overledger, + "environment", + ], + }, db: "$.service.db", http: { type: "$.interface.http", @@ -35,6 +41,7 @@ export default { async activate() { const response = await this.overledger.createHook({ path: this.getPath(), + environment: this.environment, data: { location: { technology: this.locationTechnology, @@ -51,6 +58,7 @@ export default { await this.overledger.deleteHook({ path: this.getPath(), webhookId, + environment: this.environment, }); }, }, diff --git a/components/overledger/sources/new-contract-event-instant/new-contract-event-instant.mjs b/components/overledger/sources/new-contract-event-instant/new-contract-event-instant.mjs index 3ca4b30a53e33..1ea476ebfe6c8 100644 --- a/components/overledger/sources/new-contract-event-instant/new-contract-event-instant.mjs +++ b/components/overledger/sources/new-contract-event-instant/new-contract-event-instant.mjs @@ -6,7 +6,7 @@ export default { key: "overledger-new-contract-event-instant", name: "New Smart Contract Event (Instant)", description: "Emit new event when a smart contract releases a new event.", - version: "0.0.1", + version: "0.0.2", type: "source", dedupe: "unique", props: { diff --git a/components/overledger/sources/watch-new-account-event-instant/watch-new-account-event-instant.mjs b/components/overledger/sources/watch-new-account-event-instant/watch-new-account-event-instant.mjs index 0819fc7e8641c..f0c29481e1883 100644 --- a/components/overledger/sources/watch-new-account-event-instant/watch-new-account-event-instant.mjs +++ b/components/overledger/sources/watch-new-account-event-instant/watch-new-account-event-instant.mjs @@ -6,7 +6,7 @@ export default { key: "overledger-watch-new-account-event-instant", name: "New Account Event (Instant)", description: "Emit new event for transactions to/from a specific account.", - version: "0.0.1", + version: "0.0.2", type: "source", dedupe: "unique", props: { @@ -27,7 +27,7 @@ export default { }; }, getSummary(body) { - return `New asccount event with transaction Id: ${body.transactionId}`; + return `New account event with transaction Id: ${body.transactionId}`; }, }, sampleEmit,