### Example Configuration Commands Source: https://docs.kaia.io/nodes/service-chain/install-service-chain Example commands for setting up and starting the SCN, and editing the configuration file. ```bash $ homi-darwin-amd64/bin/homi setup ... $ kscn-darwin-amd64/bin/kscnd start $ vi kscn-darwin-amd64/conf/kscnd.conf ``` -------------------------------- ### Clone and Install Service Chain Value Transfer Examples Source: https://docs.kaia.io/nodes/service-chain/quick-start/value-transfer Clone the repository and install dependencies to get started with service chain value transfer examples. ```bash $ git clone https://github.com/klaytn/servicechain-value-transfer-examples $ cd servicechain-value-transfer-examples $ npm install $ cd erc20 ``` -------------------------------- ### Install Dependencies for Kaia GA Example Source: https://docs.kaia.io/build/tutorials/ga-tutorial/ga-integration Sets up a new project directory, initializes npm, and installs necessary libraries including ethers-ext and ethers v6. ```bash mkdir kaia-ga-example cd kaia-ga-example npm init -y npm install --save @kaiachain/ethers-ext ethers@6 dotenv ``` -------------------------------- ### Configure and Start Node with Compression (Package Installation) Source: https://docs.kaia.io/misc/operation/optimize-storage Configure your network settings and start the Kaia node. Compression is enabled by default in v2.1.0 and later. Verify the node status and logs. ```bash # Configure network in kend.conf sudo vi /etc/kend/conf/kend.conf # Set: NETWORK=mainnet or NETWORK=kairos # Start node (compression enabled by default in v2.1.0+) kend start # Verify kend status tail -f /var/kend/logs/kend.out ``` -------------------------------- ### React and TypeScript Example Starter Project Source: https://docs.kaia.io/references/sdk/ethers-ext/v6/gas-abstraction/gasless This snippet demonstrates a full example of setting up a React and TypeScript project for gasless transactions using ethers-ext. It includes wallet setup, ERC20 token interaction, and gasless swap router usage. ```typescript import { ethers, Wallet, JsonRpcProvider } from "ethers"; import { gasless } from "@ethers-ext/core"; // Replace with ERC20 token address to be spent const tokenAddr = "0xcB00BA2cAb67A3771f9ca1Fa48FDa8881B457750"; // Kairos:TEST token // Replace with your wallet address and private key const senderAddr = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"; const senderPriv = "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"; const provider = new ethers.JsonRpcProvider("https://public-en-kairos.node.kaia.io"); const wallet = new Wallet(senderPriv, provider); const ERC20_ABI = [ "function decimals() view returns (uint8)", "function symbol() view returns (string)", "function allowance(address owner, address spender) view returns (uint256)", "function balanceOf(address owner) view returns (uint256)" ]; // senderAddr wants to swap the ERC20 token for at least 0.01 KAIA so she can execute the AppTx. async function main() { const appTxFee = ethers.parseEther("0.01").toString(); // Query the environment console.log(`Using token at address: ${tokenAddr}`); const token = new ethers.Contract(tokenAddr, ERC20_ABI, provider); const tokenSymbol = await token.symbol(); const tokenDecimals = await token.decimals(); const tokenBalance = await token.balanceOf(senderAddr); console.log(`\nInitial balance of the sender ${senderAddr}`); console.log(`- ${ethers.formatEther(await provider.getBalance(senderAddr))} KAIA`); console.log(`- ${ethers.formatUnits(tokenBalance, tokenDecimals)} ${tokenSymbol}`); const router = await gasless.getGaslessSwapRouter(provider); const routerAddr = await router.getAddress(); const isTokenSupported = await router.isTokenSupported(tokenAddr); const commissionRate = Number(await router.commissionRate()); console.log(`\nGaslessSwapRouter address: ${routerAddr}`); console.log(`- The token is supported: ${isTokenSupported}`); console.log(`- Commission rate: ${commissionRate} bps`); // If sender hasn't approved, include ApproveTx first. const allowance = await token.allowance(senderAddr, routerAddr); const approveRequired = (allowance == 0n); const txs = []; if (approveRequired) { console.log("\nAdding ApproveTx because allowance is 0"); const approveTx = await gasless.getApproveTx( provider, senderAddr, tokenAddr, routerAddr, gasPrice, ); txs.push(approveTx); } else { console.log("\nNo ApproveTx needed"); } // - amountRepay (KAIA) is the cost of LendTx, ApproveTx, and SwapTx. The block miner shall fund it first, // then the sender has to repay from the swap output. // - minAmountOut (KAIA) is the required amount of the swap output. It must be enough to cover the amountRepay // and pay the commission, still leaving appTxFee. // - amountIn (token) is the amount of the token to be swapped to produce minAmountOut plus slippage. console.log("\nCalculating the amount of the token to be swapped..."); const gasPrice = Number((await provider.getFeeData()).gasPrice); console.log(`- gasPrice: ${ethers.formatUnits(gasPrice, "gwei")} gkei`); const amountRepay = gasless.getAmountRepay(approveRequired, gasPrice); console.log(`- amountRepay: ${ethers.formatEther(amountRepay)} KAIA`); const minAmountOut = gasless.getMinAmountOut(amountRepay, appTxFee, commissionRate); console.log(`- minAmountOut: ${ethers.formatEther(minAmountOut)} KAIA`); const slippageBps = 50 // 0.5% const amountIn = await gasless.getAmountIn(router, tokenAddr, minAmountOut, slippageBps); console.log(`- amountIn: ${ethers.formatUnits(amountIn, tokenDecimals)} ${tokenSymbol}`); if (tokenBalance < amountIn) { console.log(`\nInsufficient balance of the token: ${ethers.formatUnits(tokenBalance, tokenDecimals)} ${tokenSymbol}`); console.log(`- Please transfer more ${tokenSymbol} to the sender ${senderAddr}`); return; } const swapTx = await gasless.getSwapTx( provider, senderAddr, tokenAddr, routerAddr, amountIn, minAmountOut, amountRepay, gasPrice, approveRequired, ); txs.push(swapTx); console.log("\nSending transactions..."); const sentTxs = await wallet.sendTransactions(txs); for (const tx of sentTxs) { console.log(`- Tx sent: (nonce: ${tx.nonce}) ${tx.hash}`); } console.log("\nWaiting for transactions to be mined..."); let blockNum = 0; for (const sentTx of sentTxs) { const receipt = await sentTx.wait(); console.log(`- Tx mined at block ${receipt.blockNumber}`); blockNum = receipt.blockNumber; } console.log("\nListing the block's transactions related to the sender..."); } main().catch((error) => { console.error(error); process.exitCode = 1; }); ``` -------------------------------- ### Complete Gas-Free Swap Integration Example Source: https://docs.kaia.io/build/tutorials/integrate-gas-free-usdt-kaia-swap This comprehensive JavaScript example integrates gas-free USDT swaps on KAIA. It includes setup, contract interactions, permit signature generation, and API calls. Ensure you have the necessary libraries installed (`ethers-ext`, `node-fetch`). ```javascript const { JsonRpcProvider, Wallet } = require('@kaiachain/ethers-ext/v6'); const { Contract, parseUnits, formatUnits, Signature } = require('ethers'); async function fetchJson(url, init) { if (typeof fetch !== 'undefined') { return fetch(url, init); } const { default: nodeFetch } = await import('node-fetch'); return nodeFetch(url, init); } const GASLESS_SWAP_ABI = [ 'function usdtToken() view returns (address)', 'function wkaiaToken() view returns (address)', 'function maxUsdtAmount() view returns (uint256)', 'function getExpectedOutput(address tokenIn, address tokenOut, uint256 amountIn) view returns (uint256)', 'function executeSwapWithPermit(address user, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin, uint256 deadline, uint8 v, bytes32 r, bytes32 s)', ]; const ERC20_METADATA_ABI = [ 'function decimals() view returns (uint8)', 'function symbol() view returns (string)', 'function name() view returns (string)', 'function nonces(address owner) view returns (uint256)', 'function balanceOf(address owner) view returns (uint256)', ]; async function buildPermitSignature({ token, owner, spender, value, deadline, domainVersion = '1' }) { const [name, version, network, verifyingContract, nonce] = await Promise.all([ token.name(), Promise.resolve(domainVersion), owner.provider.getNetwork(), token.getAddress(), token.nonces(owner.address), ]); const domain = { name, version, chainId: Number(network.chainId), verifyingContract, }; const types = { Permit: [ { name: 'owner', type: 'address' }, { name: 'spender', type: 'address' }, { name: 'value', type: 'uint256' }, { name: 'nonce', type: 'uint256' }, { name: 'deadline', type: 'uint256' }, ], }; const message = { owner: owner.address, spender, value, nonce, deadline, }; return Signature.from(await owner.signTypedData(domain, types, message)); } async function executeGaslessSwap({ rpcUrl, serverUrl, userWallet, contractAddress, amountIn = '0.01', // Amount in USDT slippageBps = 50, // 0.5% slippage permitDeadlineSeconds = 600 // 10 minutes }) { console.log('🚀 Starting gasless swap'); const provider = new JsonRpcProvider(rpcUrl); const wallet = userWallet.connect(provider); const swap = new Contract(contractAddress, GASLESS_SWAP_ABI, provider); // Get token addresses from contract const [tokenInAddress, tokenOutAddress, maxUsdtAmount] = await Promise.all([ swap.usdtToken(), swap.wkaiaToken(), swap.maxUsdtAmount(), ]); const tokenIn = new Contract(tokenInAddress, ERC20_METADATA_ABI, provider); const tokenOut = new Contract(tokenOutAddress, ERC20_METADATA_ABI, provider); const [tokenInDecimals, tokenOutDecimals, tokenInSymbol, tokenOutSymbol] = await Promise.all([ tokenIn.decimals(), tokenOut.decimals(), tokenIn.symbol(), tokenOut.symbol(), ]); const amountInWei = parseUnits(amountIn, tokenInDecimals); // Check if amount exceeds contract maximum if (amountInWei > maxUsdtAmount) { throw new Error(`Amount (${amountIn} ${tokenInSymbol}) exceeds contract cap (${formatUnits(maxUsdtAmount, tokenInDecimals)} ${tokenInSymbol})`); } // Get expected output and calculate minimum with slippage const expectedOut = await swap.getExpectedOutput(tokenInAddress, tokenOutAddress, amountInWei); const amountOutMin = (expectedOut * BigInt(10_000 - slippageBps)) / 10_000n; // Create permit signature const deadline = BigInt(Math.floor(Date.now() / 1000) + permitDeadlineSeconds); const signature = await buildPermitSignature({ token: tokenIn, owner: wallet, spender: contractAddress, value: amountInWei, deadline, }); // Prepare API payload const payload = { swap: { user: wallet.address, tokenIn: tokenInAddress, tokenOut: tokenOutAddress, amountIn: amountInWei.toString(), amountOutMin: amountOutMin.toString(), deadline: deadline.toString(), }, permitSignature: signature.serialized, }; console.log('From:', wallet.address); console.log('Swap amount:', formatUnits(amountInWei, tokenInDecimals), tokenInSymbol); console.log('Minimum out:', formatUnits(amountOutMin, tokenOutDecimals), tokenOutSymbol); // Check balance before swap const balanceBefore = await provider.getBalance(wallet.address); // Call the API const response = await fetchJson(`${serverUrl}/api/gasFreeSwapKaia`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`Gasless swap API error: ${response.statusText}`); } const result = await response.json(); console.log('Swap result:', result); // Verify balance after swap const balanceAfter = await provider.getBalance(wallet.address); console.log('Balance before:', formatUnits(balanceBefore, 18), 'KAIA'); console.log('Balance after:', formatUnits(balanceAfter, 18), 'KAIA'); return result; } // Example usage (replace with your actual values): /* executeGaslessSwap({ rpcUrl: 'YOUR_RPC_URL', serverUrl: 'YOUR_SERVER_URL', userWallet: new Wallet('YOUR_PRIVATE_KEY'), contractAddress: 'YOUR_GASLESS_SWAP_CONTRACT_ADDRESS', amountIn: '10', // Amount in USDT slippageBps: 50, // 0.5% slippage permitDeadlineSeconds: 600 // 10 minutes }).catch(console.error); */ ``` -------------------------------- ### Start SCN Service Source: https://docs.kaia.io/nodes/service-chain/install-service-chain Starts the Kaia service chain node. Use `systemctl` for RPM installations or `kscnd` for Linux archive installations. ```bash ## when installed from rpm distribution $ systemctl start kscnd.service ## when installed using linux archive $ kscnd start ``` -------------------------------- ### Setup Web3-Onboard with Chains and App Metadata Source: https://docs.kaia.io/build/wallets/wallet-libraries/web3Onboard Instantiate Onboard with wallet modules, chain configurations (including Kaia Mainnet and Testnet), and application metadata. ```javascript import Onboard from "@web3-onboard/core"; const ETH_MAINNET_RPC_URL = `Paste ETH RPC URL`; const KAIA_MAINNET_URL = `Paste KAIA MAINNET URL` const KAIROS_TESTNET_URL = `Paste KAIROS TESTNET URL` onboard = Onboard({ wallets: modules, // created in previous step chains: [ { id: "0x1", // chain ID must be in hexadecimal token: "ETH", namespace: "evm", label: "Ethereum Mainnet", rpcUrl: ETH_MAINNET_RPC_URL }, { id: "0x2019", // chain ID must be in hexadecimal token: "KAIA", namespace: "evm", label: "Kaia Mainnet", rpcUrl: KAIA_MAINNET_URL }, { id: "0x3e9", // chain ID must be in hexadecimel token: "KAIA", namespace: "evm", label: "Kairos Testnet", rpcUrl: KAIROS_TESTNET_URL }, // you can add as much supported chains as possible ], appMetadata: { name: "Kaia-web3-onboard-App", // change to your dApp name icon: "https://pbs.twimg.com/profile_images/1620693002149851137/GbBC5ZjI_400x400.jpg", // paste your icon logo: "https://pbs.twimg.com/profile_images/1620693002149851137/GbBC5ZjI_400x400.jpg", // paste your logo description: "Web3Onboard-Kaia", recommendedInjectedWallets: [ { name: "Coinbase", url: "https://wallet.coinbase.com/" }, { name: "MetaMask", url: "https://metamask.io" } ] } }); ``` -------------------------------- ### Debug Start CPU Profile Request Example Source: https://docs.kaia.io/references/json-rpc/debug/start-cpu-profile This example demonstrates how to make a JSON-RPC request to start CPU profiling. Ensure the 'params' field contains the desired output filename. ```json { "method": "debug_startCPUProfile", "id": 1, "jsonrpc": "2.0", "params": ["cpu.profile"] } ``` -------------------------------- ### Deploy Smart Contract Example Source: https://docs.kaia.io/references/sdk/ethers-ext-prior-v1-0-1/smart-contract/deploy This snippet demonstrates the full process of deploying a smart contract. It includes setting up the provider, wallet, contract factory, deploying the contract with an initial value, and waiting for the transaction receipt to get the deployed contract's address. ```javascript const ethers = require("ethers"); const { Wallet } = require("@kaiachain/ethers-ext"); const senderAddr = "0x24e8efd18d65bcb6b3ba15a4698c0b0d69d13ff7"; const senderPriv = "0x4a72b3d09c3d5e28e8652e0111f9c4ce252e8299aad95bb219a38eb0a3f4da49"; const provider = new ethers.providers.JsonRpcProvider("https://public-en-kairos.node.kaia.io"); const wallet = new Wallet(senderPriv, provider); /* compiled in remix.ethereum.org (compiler: 0.8.18, optimizer: false) // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; contract Counter { uint256 public number; event SetNumber(uint256 number); constructor(uint256 initNumber) { number = initNumber; } function setNumber(uint256 newNumber) public { number = newNumber; emit SetNumber(number); } function increment() public { number++; emit SetNumber(number); } } */ const bytecode = "0x608060405234801561001057600080fd5b5060405161031a38038061031a8339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610264806100b66000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80633fb5c1cb146100465780638381f58a14610062578063d09de08a14610080575b600080fd5b610060600480360381019061005b9190610160565b61008a565b005b61006a6100cd565b604051610077919061019c565b60405180910390f35b6100886100d3565b005b806000819055507f331bb01bcf77ec721a35a558a7984e8e6ca33b507d3ee1dd13b76f64381e54d46000546040516100c2919061019c565b60405180910390a150565b60005481565b6000808154809291906100e5906101e6565b91905055507f331bb01bcf77ec721a35a558a7984e8e6ca33b507d3ee1dd13b76f64381e54d460005460405161011b919061019c565b60405180910390a1565b600080fd5b6000819050919050565b61013d8161012a565b811461014857600080fd5b50565b60008135905061015a81610134565b92915050565b60006020828403121561017657610175610125565b5b60006101848482850161014b565b91505092915050565b6101968161012a565b82525050565b60006020820190506101b1600083018461018d565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006101f18261012a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610223576102226101b7565b5b60018201905091905056fea264697066735822122012162749eb9714a6df7a34741c39edb78cf6e3d6d3e888872232594da5a1353164736f6c63430008120033"; const abi = '[{"inputs":[{"internalType":"uint256","name":"initNumber","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"number","type":"uint256"}],"name":"SetNumber","type":"event"},{"inputs":[],"name":"increment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newNumber","type":"uint256"}],"name":"setNumber","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; async function main() { const factory = new ethers.ContractFactory(abi, bytecode, wallet); const contract = await factory.deploy(100); const sentTx = contract.deployTransaction; const receipt = await sentTx.wait(); console.log("receipt", receipt); console.log("deployed address", receipt.contractAddress); } main(); ``` -------------------------------- ### Navigate to Project Directory Source: https://docs.kaia.io/minidapps/survey-minidapp/intro Change the directory into the cloned folder to begin the local installation process. ```bash cd ExampleMiniDapp ``` -------------------------------- ### Launch the dApp Source: https://docs.kaia.io/build/get-started/scaffold-eth-get-started Start the Next.js dApp on your localhost after configuration. ```bash yarn start ``` -------------------------------- ### Debug Start Go Trace JSON RPC Request Example Source: https://docs.kaia.io/references/json-rpc/debug/start-go-trace This example shows the JSON structure for a request to start a Go runtime trace using the debug_startGoTrace method. The 'params' field specifies the output filename. ```json { "method": "debug_startGoTrace", "id": 1, "jsonrpc": "2.0", "params": [ "go.trace" ] } ``` -------------------------------- ### Create Project Directory Source: https://docs.kaia.io/build/tutorials/buy-me-a-coffee Initialize the main project folder for the Buy Me a Coffee dApp. ```bash mkdir BuyMeACoffee cd BuyMeACoffee ``` -------------------------------- ### Get Help for Ken Account Command Source: https://docs.kaia.io/nodes/endpoint-node/ken-cli-commands Example of how to get detailed usage information for a specific Ken command, such as 'account'. ```bash ken account -h ``` -------------------------------- ### GET /api/balance Request (with API Key) Source: https://docs.kaia.io/build/tutorials/integrate-fee-delegation-service Example of a GET request to the /api/balance endpoint when using an API key for authentication. ```http GET /api/balance Authorization: Bearer your_api_key_here ``` -------------------------------- ### Navigate to Project Directory Source: https://docs.kaia.io/build/get-started/scaffold-eth-get-started After the project setup is complete, change into your new project's directory. ```bash cd project-name ``` -------------------------------- ### Setup Wallet Client and Account with Viem Source: https://docs.kaia.io/references/sdk/viem Set up a wallet client for performing actions like sending transactions and signing messages. Requires specifying the chain, transport, and account details. ```typescript import { createWalletClient } from 'viem' import { privateKeyToAccount } from 'viem/accounts' const walletClient = createWalletClient({ chain: klaytnBaobab, transport: http("https://public-en-kairos.node.kaia.io") }) const account = privateKeyToAccount("PASTE PRIVATE KEY HERE"); ``` -------------------------------- ### Eth Get Balance JSON-RPC Response Example Source: https://docs.kaia.io/references/json-rpc/eth/get-balance Example of a successful JSON-RPC response for eth_getBalance, showing the balance in wei. ```json { "jsonrpc": "2.0", "id": 0, "error": { "code": -32700, "message": "Parse error", "data": "string" }, "result": 158972490234375000 } ``` -------------------------------- ### Install Viem SDK Source: https://docs.kaia.io/references/sdk/viem Install the Viem library using npm. This is the first step to using Viem for Kaia Network interactions. ```bash npm i viem ``` -------------------------------- ### Get Total Supply Example (JSON-RPC) Source: https://docs.kaia.io/references/json-rpc/kaia/get-total-supply This example demonstrates how to call the kaia_getTotalSupply method using JSON-RPC to get the latest total supply. It specifies the method, a unique ID, the JSON-RPC version, and parameters, which in this case is 'latest' to signify the most recent block. ```json { "method": "kaia_getTotalSupply", "id": 1, "jsonrpc": "2.0", "params": [ "latest" ] } ``` -------------------------------- ### Environment Setup for Fee Delegation Source: https://docs.kaia.io/build/tutorials/fee-delegation-example Initialize a Node.js project and install the necessary packages, including @kaiachain/ethers-ext and ethers. Node.js version 22 or later is recommended. ```bash mkdir feedelegation_server cd feedelegation_server npm init -y npm install - -save @kaiachain/ethers-ext@^1.2.0 ethers@6 ``` -------------------------------- ### JSON-RPC Get Account Key Response Example Source: https://docs.kaia.io/references/json-rpc/kaia/get-account-key This is a general example of a JSON-RPC response for the getAccountKey method, illustrating both error and result structures. ```json { "jsonrpc": "2.0", "id": 0, "error": { "code": -32700, "message": "Parse error", "data": "string" }, "result": { "key": {}, "keyType": 0 } } ``` -------------------------------- ### Eth Get Code JSON-RPC Response Example Source: https://docs.kaia.io/references/json-rpc/eth/get-code This is an example of a successful JSON-RPC response for the eth_getCode method, returning the contract's bytecode. ```json { "jsonrpc": "2.0", "id": 0, "error": { "code": -32700, "message": "Parse error", "data": "string" }, "result": "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056" } ``` -------------------------------- ### Fetch Group Example Source: https://docs.kaia.io/minidapps/survey-minidapp/api-reference Example of how to fetch group members using the API. It makes a GET request to the /api/group/members endpoint with a survey ID. ```typescript // Fetching group const getGroup = async (id: string) => { const result = await fetch(`${API_URL}/api/group/members?id=${id}`, { method: "GET", headers: { "Content-Type": "application/json", }, }); if (result.status !== 200) { console.log("Failed to fetch group members"); return { members: [], groupId: "" }; } ``` -------------------------------- ### Configure Private Key Source: https://docs.kaia.io/build/tutorials/pyth-real-time-price Create a .env file in your project root and add your private key for authentication. ```bash PRIVATE_KEY="0xDEAD....." // REPLACE WITH YOUR PRIVATE KEY ``` -------------------------------- ### Get Header By Number JSON-RPC Request Source: https://docs.kaia.io/references/json-rpc/kaia/get-header-by-number This is an example of a JSON-RPC request to get a block header by its number. Ensure the 'id' and 'params' are correctly formatted. ```json { "jsonrpc": "2.0", "method": "getHeaderByNumber", "params": [ "0x1" ], "id": 1 } ``` -------------------------------- ### Initialize Foundry Project Source: https://docs.kaia.io/build/smart-contracts/deploy/foundry Start a new Foundry project to begin smart contract development. ```bash forge init foundry_example ``` -------------------------------- ### Deploy Smart Contract using ethers-ext v6 Source: https://docs.kaia.io/references/sdk/ethers-ext/v6/basic-transaction/smart-contract-deploy This snippet demonstrates the complete process of deploying a smart contract. It includes setting up the provider, wallet, defining the transaction with the compiled bytecode, sending the transaction, and waiting for the receipt. Ensure you have the correct sender address, private key, and provider URL. ```javascript const ethers = require("ethers"); const { Wallet, TxType } = require("@kaiachain/ethers-ext/v6"); const senderAddr = "0xa2a8854b1802d8cd5de631e690817c253d6a9153"; const senderPriv = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8"; const provider = new ethers.JsonRpcProvider("https://public-en-kairos.node.kaia.io"); const wallet = new Wallet(senderPriv, provider); async function main() { const tx = { type: TxType.SmartContractDeploy, from: senderAddr, value: 0, gasLimit: 1_000_000, input: "0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220e0f4e7861cb6d7acf0f61d34896310975b57b5bc109681dbbfb2e548ef7546b364736f6c63430008120033", humanReadable: false, // must be false codeFormat: 0, // must be 0 }; const sentTx = await wallet.sendTransaction(tx); console.log("sentTx", sentTx.hash); const receipt = await sentTx.wait(); console.log("receipt", receipt); } main(); ``` -------------------------------- ### Start Grafana Server on macOS Source: https://docs.kaia.io/nodes/debugging/monitoring-setup Starts the Grafana server using Homebrew services on macOS. Ensure Grafana is installed via Homebrew before running this command. ```shell # macOS using Homebrew brew services start grafana ``` -------------------------------- ### Initialize Web3.js with Gasless Features Source: https://docs.kaia.io/references/sdk/web3js-ext/gas-abstraction/gasless Import and initialize Web3.js with the extended @kaiachain/web3js-ext package. Configure the provider and sender account using a private key for signing transactions. ```javascript const { Web3 } = require("@kaiachain/web3js-ext"); // Replace with ERC20 token address to be spent const tokenAddr = "0xcB00BA2cAb67A3771f9ca1Fa48FDa8881B457750"; // Kairos:TEST token // Replace with your wallet address and private key const senderAddr = "0x24e8efd18d65bcb6b3ba15a4698c0b0d69d13ff7"; const senderPriv = "0x4a72b3d09c3d5e28e8652e0111f9c4ce252e8299aad95bb219a38eb0a3f4da49"; const provider = new Web3.providers.HttpProvider("https://public-en-kairos.node.kaia.io"); const web3 = new Web3(provider); const senderAccount = web3.eth.accounts.privateKeyToAccount(senderPriv); ``` -------------------------------- ### ESM or TypeScript Setup with ethers-ext Source: https://docs.kaia.io/references/sdk/ethers-ext-prior-v1-0-1/getting-started Import Wallet and JsonRpcProvider from @kaiachain/ethers-ext for use in ESM or TypeScript projects. This example shows the setup for a new provider and wallet. ```javascript import { Wallet, JsonRpcProvider } from "@kaiachain/ethers-ext"; const provider = new JsonRpcProvider("https://public-en-kairos.node.kaia.io"); const wallet = new Wallet("", provider); ``` -------------------------------- ### Deploying a Smart Contract Source: https://docs.kaia.io/references/sdk/ethers-ext/v6/smart-contract/deploy This snippet demonstrates the full process of deploying a smart contract. It includes setting up the provider and wallet, defining the contract's bytecode and ABI, creating a contract factory, deploying the contract with an initial value, and waiting for the deployment transaction receipt. ```javascript const ethers = require("ethers"); const { Wallet } = require("@kaiachain/ethers-ext/v6"); const senderAddr = "0x24e8efd18d65bcb6b3ba15a4698c0b0d69d13ff7"; const senderPriv = "0x4a72b3d09c3d5e28e8652e0111f9c4ce252e8299aad95bb219a38eb0a3f4da49"; const provider = new ethers.JsonRpcProvider("https://public-en-kairos.node.kaia.io"); const wallet = new Wallet(senderPriv, provider); /* compiled in remix.ethereum.org (compiler: 0.8.18, optimizer: false) // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; contract Counter { uint256 public number; event SetNumber(uint256 number); constructor(uint256 initNumber) { number = initNumber; } function setNumber(uint256 newNumber) public { number = newNumber; emit SetNumber(number); } function increment() public { number++; emit SetNumber(number); } } */ const bytecode = "0x608060405234801561001057600080fd5b5060405161031a38038061031a8339818101604052810190610032919061007a565b80600081905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610264806100b66000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80633fb5c1cb146100465780638381f58a14610062578063d09de08a14610080575b600080fd5b610060600480360381019061005b9190610160565b61008a565b005b61006a6100cd565b604051919061019c565b60405180910390f35b6100886100d3565b005b806000819055507f331bb01bcf77ec721a35a558a7984e8e6ca33b507d3ee1dd13b76f64381e54d46000546040516100c2919061019c565b60405180910390a150565b60005481565b6000808154809291906100e5906101e6565b91905055507f331bb01bcf77ec721a35a558a7984e8e6ca33b507d3ee1dd13b76f64381e54d460005460405161011b919061019c565b60405180910390a1565b600080fd5b6000819050919050565b61013d8161012a565b811461014857600080fd5b50565b60008135905061015a81610134565b92915050565b60006020828403121561017657610175610125565b5b60006101848482850161014b565b91505092915050565b6101968161012a565b82525050565b60006020820190506101b1600083018461018d565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006101f18261012a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610223576102226101b7565b5b60018201905091905056fea264697066735822122012162749eb9714a6df7a34741c39edb78cf6e3d6d3e888872232594da5a1353164736f6c63430008120033" const abi = '[{"inputs":[{"internalType":"uint256","name":"initNumber","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"number","type":"uint256"}],"name":"SetNumber","type":"event"},{"inputs":[],"name":"increment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"number","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newNumber","type":"uint256"}],"name":"setNumber","outputs":[],"stateMutability":"nonpayable","type":"function"}]'; async function main() { const factory = new ethers.ContractFactory(abi, bytecode, wallet); const contract = await factory.deploy(100); const sentTx = contract.deployTransaction; const receipt = await sentTx.wait(); console.log("receipt", receipt); console.log("deployed address", receipt.contractAddress); } main(); ``` -------------------------------- ### GET /api/balance Request (without API Key) Source: https://docs.kaia.io/build/tutorials/integrate-fee-delegation-service Example of a GET request to the /api/balance endpoint when not using an API key, requiring the sender's address as a query parameter. ```http GET /api/balance?address=0x742d35Cc6634C0532925a3b8D2A4DDDeAe0e4Cd3 ``` -------------------------------- ### Install Web3-Onboard Core Source: https://docs.kaia.io/build/wallets/wallet-libraries/web3Onboard Install the core Web3-Onboard package using npm. ```bash npm i @web3-onboard/core ``` -------------------------------- ### Setting up Gas Abstraction Source: https://docs.kaia.io/references/sdk/ethers-ext/v6/gas-abstraction/gasless This snippet demonstrates the initial setup for gas abstraction using the ethers-ext library. Ensure you have the necessary packages installed. ```typescript import { ethers } from "ethers"; import { GasAbstraction } from "ethers-ext"; // Replace with your actual RPC URL and chain ID const provider = new ethers.JsonRpcProvider("YOUR_RPC_URL"); const chainId = 1337; // Example chain ID const gasAbstraction = new GasAbstraction(provider, chainId); async function setupGasAbstraction() { // Further setup or configuration would go here console.log("Gas abstraction setup complete."); } setupGasAbstraction(); ``` -------------------------------- ### Full Code Example for Kaia Safe API Kit Interaction Source: https://docs.kaia.io/build/wallets/wallet-config/create-and-manage-wallets-securely A complete code example demonstrating the setup and execution of a Safe transaction using the Kaia Safe API Kit. ```javascript import SafeApiKit from "@safe-global/api-kit"; import Safe from "@safe-global/protocol-kit"; import { OperationType } from "@safe-global/safe-core-sdk-types"; import { ethers } from "ethers"; ``` -------------------------------- ### Get Account Key using cURL Source: https://docs.kaia.io/references/json-rpc/kaia/get-account-key Example of how to call the getAccountKey JSON-RPC method using cURL. ```shell curl -X 'POST' \ ```