Note: For now the configuration is fixed and cannot be changed.
Typescript Function Context
When writing the Web3 Function, it is very helpful to understand the context Gelato injects into the execution, providing additional features to widen the Web3 Functions applicability.
Web3Functions are stateless scripts, that will run in a new & empty memory context on every execution. If you need to manage some state variable, we provide a simple key/value store that you can access from your web3 function context.
See the above example to read & update values from your storage:
import { Web3Function, Web3FunctionContext,} from"@gelatonetwork/web3-functions-sdk";Web3Function.onRun(async (context:Web3FunctionContext) => {const { storage,multiChainProvider } = context;constprovider=multiChainProvider.default();// Use storage to retrieve previous state (stored values are always string)constlastBlockStr= (awaitstorage.get("lastBlockNumber")) ??"0";constlastBlock=parseInt(lastBlockStr);console.log(`Last block: ${lastBlock}`);constnewBlock=awaitprovider.getBlockNumber();console.log(`New block: ${newBlock}`);if (newBlock > lastBlock) {// Update storage to persist your current state (values must be cast to string)awaitstorage.set("lastBlockNumber",newBlock.toString()); }return { canExec:false, message:`Updated block number: ${newBlock.toString()}`, };});
To populate the storage values in your testing, in the same directory as your web3 function, create a file storage.json and fill in the storage values.
{"lastBlockNumber":"1000"}
Test out the storage web3 function:
npx hardhat w3f-run storage --logs
Secrets
In the same directory as your web3 function, create a .env file and fill up your secrets.
COINGECKO_API=https://api.coingecko.com/api/v3
Access your secrets from the Web3Function context:
// Get api from secretsconstcoingeckoApi=awaitcontext.secrets.get("COINGECKO_API");if (!coingeckoApi) {return { canExec:false, message:`COINGECKO_API not set in secrets` }; }
Test your web3 function using secrets:
npxhardhatw3f-runsecrets--logs
When deploying a task, you will be able to set your web3 function secrets on our UI or using the SDK, see here
import hre from"hardhat";import { AutomateSDK, Web3Function } from"@gelatonetwork/automate-sdk";const { ethers,w3f } = hre;constadBoardW3f=w3f.get("advertising-board");const [deployer] =awaitethers.getSigners();constchainId= (awaitethers.provider.getNetwork()).chainId;constautomate=newAutomateSDK(chainId, deployer);constweb3Function=newWeb3Function(chainId, deployer);// Deploy Web3Function on IPFSconsole.log("Deploying Web3Function on IPFS...");constcid=awaitadBoardW3f.deploy();console.log(`Web3Function IPFS CID: ${cid}`);// Create task using automate sdkconsole.log("Creating automate task...");const { taskId,tx } =awaitautomate.createBatchExecTask({ name:"Web3Function - Ad Board", web3FunctionHash: cid, web3FunctionArgs: {},});awaittx.wait();console.log(`Task created, taskId: ${taskId} (tx hash: ${tx.hash})`);console.log(`> https://beta.app.gelato.network/task/${taskId}?chainId=${chainId}`);// Set task specific secretsconstsecrets=adBoardW3f.getSecrets();if (Object.keys(secrets).length>0) {awaitweb3Function.secrets.set(secrets, taskId);console.log(`Secrets set`);}
Multichain Provider
The multichainProvider allows us to instantiate RPC providers for every network Gelato is deployed on.
import { Web3Function, Web3FunctionContext,} from"@gelatonetwork/web3-functions-sdk";Web3Function.onRun(async (context:Web3FunctionContext) => {const { multiChainProvider } = context;// multichainProvider.default() will instantiate// the provider of the chain the W3F is deployedconstprovider=multiChainProvider.default();// passing the chainId as follows, we can instantiate// a rpc provider for that networkconstpolygonProvider=multiChainProvider.chainId(137)...// This method fetches the number of remaining RPC calls,// allowing dynamic adaptations based on the user's plan limits.constremainingCalls=awaitmultiChainProvider.nbRpcCallsRemaining();...}
When testing locally, we can provide the different providers by including them in .env at the root folder.
// .env file
PROVIDER_URLS=RPC1,RPC2
Interoperability with Other Libraries
Although multiChainProvider is designed to work seamlessly within the Gelato Web3 Functions SDK, it is possible to extract the underlying RPC URL and use it with other client libraries. This flexibility is valuable for developers who prefer or require features from other libraries, such as viem.
Here's an example of how to utilize the RPC URL from multiChainProvider with the viem library, which can be useful if you need to leverage features specific to viem:
import { createPublicClient, http } from"viem";import { polygon } from"viem/chains";Web3Function.onRun(async (context:Web3FunctionContext) => {const { multiChainProvider } = context;constprovider=multiChainProvider.default();consturl=provider.connection.url;// Initialize viem client with the extracted URLconstrpc=createPublicClient({ chain: polygon, transport:http(url), });// Now you can use the viem client for your operations// ...});
Gelato Arguments
Gelato injects the chainId, the gasPrice, and the taskId into the context.
chainId: The unique number identifying the blockchain network where the function is running.
gasPrice: The cost of executing transactions on the blockchain.
taskId: A string that uniquely identifies the task.