In both use cases we will validate a smart contract function transfer, in other words, we will validate a transfer of ERC-20 tokens.
Before we start, here is an example transfer method function call in solidity that we will call to validate:
Use Case #1: validate a transaction of transfer of ERC-20 tokens using dApp frontend and dApp backend
Initialize Contract
In the dApp frontend, initialize a contract and connect it to a signer.
Now to validate a transaction, we need to get the information about a transaction that is about to happen without actually executing it. And for that, we can use the ethers.js contract.populateTransaction function that returns populatedTransaction object to represent the transaction that would need to be signed and submitted to the network for execution without actually executing it.
Let’s populate a transaction with a transfer method for validation. First, import our CUBE3 frontend library and create CUBE3 validation object. For that - use constructCube3Validation method that takes in two parameters - populatedTransaction object (Make sure to set chainId and value field, where value field is amount of ether being interacted with in the blockchain) and a boolean trackNonce used to determine whether to track nonce.
FRONTENDFRONTENDimport { constructCube3Validation } from'@cube3/sdk-ui'import { BigNumber } from"ethers"//Our previous code <...>consttxData=awaitconnectedTokenContract.populateTransaction.transfer("to", amount)//make sure to have your chainId and value defined inside this objecttxData.chainId =5;txData.value =BigNumber.from(0);constcube3TransactionData=awaitconstructCube3Validation(txData,true);
Send to Backend
Send CUBE3 data to the dApp (your) backend with cube3TransactionData in the request body.
Now let’s review the dApps backend code. We just sent cube3TransactionData in the body to the dApps backend. From here we can ask CUBE3 to validate transaction for us using cube3ValidateTransaction method from @cube3/sdk-nodejs library. For that, you need to set your apiKey andvalidationUrl.
Now we can get a validation response from the dApps backend and check if our transaction (token transfer) was valid or not. At this point we are done with our detection.
Another method of checking would be inspecting your browser:
Inspect > Network > Validate > Response
FRONTENDimport { Cube3ValidationResponse } from'@cube3/sdk-nodejs'const cube3ValidationResponse: Cube3ValidationResponse = await fetch('https://validation.cube3.ai/api/validation', requestParams).then(
response =>response.json() asPromise<Cube3ValidationResponse>)if (cube3ValidationResponse.valid ===true) {*//Validation is done, now you can safely do a transaction on a blockchain*constreceipt=awaitsigner.sendTransaction(txData);console.log(receipt)}
Save to Cube
After sending the transaction to the chain, we will save the transaction ID to the system. To do so, you will need a transaction ID and an internal CUBE3 transaction ID. However, we cannot do that on frontend because our API-KEY would get exposed. So, we will call dApps backend with receipt hash and internal CUBE3 transaction ID in body.
Use Case #2: Validate a transfer of ERC-20 tokens in the backend only
The code is going to be very similar to our previous use case.
To interact with a contract we will again use ethers.js to initialize a wallet, provider, and get a signer. To initialize a provider we can use any blockchain API (Alchemy, QuickNode, etc.) but in this use case, we are gonna use Infura(RPC). After that, we are going to populate transaction. Again, don’t forget to set chainId and transaction value.
In the previous use case, we used constructCube3Validation that returned Cube3TransactionData from @cube3/sdk-ui. In this case - we are going to construct CUBE3 data ourselves. For this, we will still use @cube3/sdk-ui library simply for accessing Cube3Transaction object that in the previous use case was generated for us.
Now we can validate using @cube3/sdk-nodejs libraries cube3ValidateTransaction method. At this point, we are done with our detection.
constcube3ValidatedTransaction=awaitcube3ValidateTransaction(validationUrl, apiKey, cube3ValidationData)if (cube3ValidatedTransaction.valid ===true) {//Validation is done, now you can safely do a transaction on a blockchainconstreceipt=awaitsigner.sendTransaction(txData);console.log(receipt)}
After sending the transaction to the chain, we save the transaction ID to the system. To do so, you will need a transaction ID and an internal CUBE3 transaction ID.