From ea51ea1478393d336985d8eedb92c6c9d95e9da7 Mon Sep 17 00:00:00 2001 From: nhussein11 Date: Tue, 18 Nov 2025 12:20:22 -0300 Subject: [PATCH 1/3] fix: viem library to evm --- .../smart-contracts/libraries/viem/compile.ts | 102 +++++++++++------- .../smart-contracts/libraries/viem/deploy.ts | 32 ++++-- .../libraries/viem/fetchLastBlock.ts | 4 +- .../libraries/viem/interact.ts | 16 +-- smart-contracts/libraries/viem.md | 18 ++-- 5 files changed, 105 insertions(+), 67 deletions(-) diff --git a/.snippets/code/smart-contracts/libraries/viem/compile.ts b/.snippets/code/smart-contracts/libraries/viem/compile.ts index 112f51759..6d91cae66 100644 --- a/.snippets/code/smart-contracts/libraries/viem/compile.ts +++ b/.snippets/code/smart-contracts/libraries/viem/compile.ts @@ -1,49 +1,76 @@ -import { compile } from '@parity/resolc'; -import { readFileSync, writeFileSync } from 'fs'; +import solc from 'solc'; +import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'; import { basename, join } from 'path'; -const compileContract = async ( +const ensureDir = (dirPath: string): void => { + if (!existsSync(dirPath)) { + mkdirSync(dirPath, { recursive: true }); + } +}; + +const compileContract = ( solidityFilePath: string, - outputDir: string -): Promise => { + abiDir: string, + artifactsDir: string +): void => { try { // Read the Solidity file const source: string = readFileSync(solidityFilePath, 'utf8'); - - // Construct the input object for the compiler - const input: Record = { - [basename(solidityFilePath)]: { content: source }, + const fileName: string = basename(solidityFilePath); + + // Construct the input object for the Solidity compiler + const input = { + language: 'Solidity', + sources: { + [fileName]: { + content: source, + }, + }, + settings: { + outputSelection: { + '*': { + '*': ['abi', 'evm.bytecode'], + }, + }, + }, }; - - console.log(`Compiling contract: ${basename(solidityFilePath)}...`); - + + console.log(`Compiling contract: ${fileName}...`); + // Compile the contract - const out = await compile(input); - - for (const contracts of Object.values(out.contracts)) { - for (const [name, contract] of Object.entries(contracts)) { - console.log(`Compiled contract: ${name}`); - + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + // Check for errors + if (output.errors) { + const errors = output.errors.filter((error: any) => error.severity === 'error'); + if (errors.length > 0) { + console.error('Compilation errors:'); + errors.forEach((err: any) => console.error(err.formattedMessage)); + return; + } + // Show warnings + const warnings = output.errors.filter((error: any) => error.severity === 'warning'); + warnings.forEach((warn: any) => console.warn(warn.formattedMessage)); + } + + // Ensure output directories exist + ensureDir(abiDir); + ensureDir(artifactsDir); + + // Process compiled contracts + for (const [sourceFile, contracts] of Object.entries(output.contracts)) { + for (const [contractName, contract] of Object.entries(contracts as any)) { + console.log(`Compiled contract: ${contractName}`); + // Write the ABI - const abiPath = join(outputDir, `${name}.json`); - writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + const abiPath = join(abiDir, `${contractName}.json`); + writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2)); console.log(`ABI saved to ${abiPath}`); - + // Write the bytecode - if ( - contract.evm && - contract.evm.bytecode && - contract.evm.bytecode.object - ) { - const bytecodePath = join(outputDir, `${name}.polkavm`); - writeFileSync( - bytecodePath, - Buffer.from(contract.evm.bytecode.object, 'hex') - ); - console.log(`Bytecode saved to ${bytecodePath}`); - } else { - console.warn(`No bytecode found for contract: ${name}`); - } + const bytecodePath = join(artifactsDir, `${contractName}.bin`); + writeFileSync(bytecodePath, (contract as any).evm.bytecode.object); + console.log(`Bytecode saved to ${bytecodePath}`); } } } catch (error) { @@ -52,6 +79,7 @@ const compileContract = async ( }; const solidityFilePath: string = './contracts/Storage.sol'; -const outputDir: string = './artifacts/'; +const abiDir: string = './abis'; +const artifactsDir: string = './artifacts'; -compileContract(solidityFilePath, outputDir); \ No newline at end of file +compileContract(solidityFilePath, abiDir, artifactsDir); \ No newline at end of file diff --git a/.snippets/code/smart-contracts/libraries/viem/deploy.ts b/.snippets/code/smart-contracts/libraries/viem/deploy.ts index c4a4ca23b..de47316a8 100644 --- a/.snippets/code/smart-contracts/libraries/viem/deploy.ts +++ b/.snippets/code/smart-contracts/libraries/viem/deploy.ts @@ -1,7 +1,13 @@ -import { readFileSync } from 'fs'; -import { join } from 'path'; -import { createWallet } from './createWallet'; -import { publicClient } from './createClient'; +import { existsSync, readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import { createWallet } from './createWallet.ts'; +import { publicClient } from './createClient.ts'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const ABIS_DIR = join(__dirname, '../abis'); +const ARTIFACTS_DIR = join(__dirname, '../artifacts'); const deployContract = async ( contractName: string, @@ -10,16 +16,20 @@ const deployContract = async ( try { console.log(`Deploying ${contractName}...`); + const abiPath = join(ABIS_DIR, `${contractName}.json`); + const bytecodePath = join(ARTIFACTS_DIR, `${contractName}.bin`); + + if (!existsSync(abiPath) || !existsSync(bytecodePath)) { + throw new Error( + `Missing artifacts for ${contractName}. Try running "npm run compile" first.` + ); + } + // Read contract artifacts const abi = JSON.parse( - readFileSync( - join(__dirname, '../artifacts', `${contractName}.json`), - 'utf8' - ) + readFileSync(abiPath, 'utf8') ); - const bytecode = `0x${readFileSync( - join(__dirname, '../artifacts', `${contractName}.polkavm`) - ).toString('hex')}` as `0x${string}`; + const bytecode = `0x${readFileSync(bytecodePath, 'utf8').trim()}` as `0x${string}`; // Create wallet const wallet = createWallet(privateKey); diff --git a/.snippets/code/smart-contracts/libraries/viem/fetchLastBlock.ts b/.snippets/code/smart-contracts/libraries/viem/fetchLastBlock.ts index 6d7c3bb75..b24073ea7 100644 --- a/.snippets/code/smart-contracts/libraries/viem/fetchLastBlock.ts +++ b/.snippets/code/smart-contracts/libraries/viem/fetchLastBlock.ts @@ -1,6 +1,6 @@ import { createPublicClient, http } from 'viem'; -const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); +const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready // Configure the Polkadot Hub chain const polkadotHubTestnet = { @@ -14,7 +14,7 @@ const polkadotHubTestnet = { }, rpcUrls: { default: { - http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], + http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready }, }, } as const; diff --git a/.snippets/code/smart-contracts/libraries/viem/interact.ts b/.snippets/code/smart-contracts/libraries/viem/interact.ts index a1b55ae42..44146481c 100644 --- a/.snippets/code/smart-contracts/libraries/viem/interact.ts +++ b/.snippets/code/smart-contracts/libraries/viem/interact.ts @@ -1,10 +1,14 @@ -import { publicClient } from './createClient'; -import { createWallet } from './createWallet'; import { readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import { publicClient } from './createClient.ts'; +import { createWallet } from './createWallet.ts'; -const STORAGE_ABI = JSON.parse( - readFileSync('./artifacts/Storage.json', 'utf8') -); +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const ABI_PATH = join(__dirname, '../abis/Storage.json'); + +const STORAGE_ABI = JSON.parse(readFileSync(ABI_PATH, 'utf8')); const interactWithStorage = async ( contractAddress: `0x${string}`, @@ -48,4 +52,4 @@ const interactWithStorage = async ( const PRIVATE_KEY = 'INSERT_PRIVATE_KEY'; const CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS'; -interactWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY); +interactWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY); \ No newline at end of file diff --git a/smart-contracts/libraries/viem.md b/smart-contracts/libraries/viem.md index 5b11f7682..351c1656d 100644 --- a/smart-contracts/libraries/viem.md +++ b/smart-contracts/libraries/viem.md @@ -6,8 +6,6 @@ categories: Smart Contracts, Tooling # viem ---8<-- 'text/smart-contracts/polkaVM-warning.md' - ## Introduction [viem](https://viem.sh/){target=\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub. @@ -37,13 +35,13 @@ viem-project/ │ └── interact.ts ├── contracts/ │ └── Storage.sol +├── abis/ +│ └── Storage.json └── artifacts/ - ├── Storage.json - └── Storage.polkavm + └── Storage.bin ``` -## Set Up the Project - +## Set Up the Proje First, create a new folder and initialize your project: ```bash @@ -54,11 +52,11 @@ npm init -y ## Install Dependencies -Install viem along with other necessary dependencies, including [@parity/resolc](https://www.npmjs.com/package/@parity/resolc){target=\_blank}, which enables to compile smart contracts to [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\_blank} bytecode: +Install viem along with other necessary dependencies, including [`solc`](https://www.npmjs.com/package/solc){target=\_blank}, which enables to compile smart contracts EVM bytecode: ```bash # Install viem and resolc -npm install viem @parity/resolc +npm install viem solc # Install TypeScript and development dependencies npm install --save-dev typescript ts-node @types/node @@ -144,8 +142,6 @@ You can use the following contract to interact with the blockchain. Paste the fo ## Compile the Contract ---8<-- 'text/smart-contracts/code-size.md' - Create a new file at `src/compile.ts` for handling contract compilation: ```typescript title="src/compile.ts" @@ -158,7 +154,7 @@ To compile your contract: npm run compile ``` -After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.polkavm` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. +After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. ## Deploy the Contract From d76256d143a926a74142a6ea8f69173aea22e961 Mon Sep 17 00:00:00 2001 From: nhussein11 Date: Tue, 18 Nov 2025 12:20:40 -0300 Subject: [PATCH 2/3] fix: llms --- .ai/categories/smart-contracts.md | 174 ++++++++++++-------- .ai/categories/tooling.md | 174 ++++++++++++-------- .ai/pages/smart-contracts-libraries-viem.md | 174 ++++++++++++-------- .ai/site-index.json | 14 +- llms-full.jsonl | 28 ++-- 5 files changed, 333 insertions(+), 231 deletions(-) diff --git a/.ai/categories/smart-contracts.md b/.ai/categories/smart-contracts.md index 1e901e36e..80c6ce257 100644 --- a/.ai/categories/smart-contracts.md +++ b/.ai/categories/smart-contracts.md @@ -9637,8 +9637,6 @@ Page Title: viem for Polkadot Hub Smart Contracts # viem -!!! smartcontract "PolkaVM Preview Release" - PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction [viem](https://viem.sh/){target=\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub. @@ -9668,13 +9666,13 @@ viem-project/ │ └── interact.ts ├── contracts/ │ └── Storage.sol +├── abis/ +│ └── Storage.json └── artifacts/ - ├── Storage.json - └── Storage.polkavm + └── Storage.bin ``` -## Set Up the Project - +## Set Up the Proje First, create a new folder and initialize your project: ```bash @@ -9685,11 +9683,11 @@ npm init -y ## Install Dependencies -Install viem along with other necessary dependencies, including [@parity/resolc](https://www.npmjs.com/package/@parity/resolc){target=\_blank}, which enables to compile smart contracts to [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\_blank} bytecode: +Install viem along with other necessary dependencies, including [`solc`](https://www.npmjs.com/package/solc){target=\_blank}, which enables to compile smart contracts EVM bytecode: ```bash # Install viem and resolc -npm install viem @parity/resolc +npm install viem solc # Install TypeScript and development dependencies npm install --save-dev typescript ts-node @types/node @@ -9792,7 +9790,7 @@ After setting up the [Public Client](https://viem.sh/docs/clients/public#public- ```js title="src/fetchLastBlock.ts" import { createPublicClient, http } from 'viem'; - const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); + const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready // Configure the Polkadot Hub chain const polkadotHubTestnet = { @@ -9806,7 +9804,7 @@ After setting up the [Public Client](https://viem.sh/docs/clients/public#public- }, rpcUrls: { default: { - http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], + http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready }, }, } as const; @@ -9909,60 +9907,82 @@ contract Storage { ## Compile the Contract -!!! note "Contracts Code Blob Size Disclaimer" - The maximum contract code blob size on Polkadot Hub networks is _100 kilobytes_, significantly larger than Ethereum’s EVM limit of 24 kilobytes. - - For detailed comparisons and migration guidelines, see the [EVM vs. PolkaVM](/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/#current-memory-limits){target=\_blank} documentation page. - Create a new file at `src/compile.ts` for handling contract compilation: ```typescript title="src/compile.ts" -import { compile } from '@parity/resolc'; -import { readFileSync, writeFileSync } from 'fs'; +import solc from 'solc'; +import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'; import { basename, join } from 'path'; -const compileContract = async ( +const ensureDir = (dirPath: string): void => { + if (!existsSync(dirPath)) { + mkdirSync(dirPath, { recursive: true }); + } +}; + +const compileContract = ( solidityFilePath: string, - outputDir: string -): Promise => { + abiDir: string, + artifactsDir: string +): void => { try { // Read the Solidity file const source: string = readFileSync(solidityFilePath, 'utf8'); - - // Construct the input object for the compiler - const input: Record = { - [basename(solidityFilePath)]: { content: source }, + const fileName: string = basename(solidityFilePath); + + // Construct the input object for the Solidity compiler + const input = { + language: 'Solidity', + sources: { + [fileName]: { + content: source, + }, + }, + settings: { + outputSelection: { + '*': { + '*': ['abi', 'evm.bytecode'], + }, + }, + }, }; - - console.log(`Compiling contract: ${basename(solidityFilePath)}...`); - + + console.log(`Compiling contract: ${fileName}...`); + // Compile the contract - const out = await compile(input); - - for (const contracts of Object.values(out.contracts)) { - for (const [name, contract] of Object.entries(contracts)) { - console.log(`Compiled contract: ${name}`); - + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + // Check for errors + if (output.errors) { + const errors = output.errors.filter((error: any) => error.severity === 'error'); + if (errors.length > 0) { + console.error('Compilation errors:'); + errors.forEach((err: any) => console.error(err.formattedMessage)); + return; + } + // Show warnings + const warnings = output.errors.filter((error: any) => error.severity === 'warning'); + warnings.forEach((warn: any) => console.warn(warn.formattedMessage)); + } + + // Ensure output directories exist + ensureDir(abiDir); + ensureDir(artifactsDir); + + // Process compiled contracts + for (const [sourceFile, contracts] of Object.entries(output.contracts)) { + for (const [contractName, contract] of Object.entries(contracts as any)) { + console.log(`Compiled contract: ${contractName}`); + // Write the ABI - const abiPath = join(outputDir, `${name}.json`); - writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + const abiPath = join(abiDir, `${contractName}.json`); + writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2)); console.log(`ABI saved to ${abiPath}`); - + // Write the bytecode - if ( - contract.evm && - contract.evm.bytecode && - contract.evm.bytecode.object - ) { - const bytecodePath = join(outputDir, `${name}.polkavm`); - writeFileSync( - bytecodePath, - Buffer.from(contract.evm.bytecode.object, 'hex') - ); - console.log(`Bytecode saved to ${bytecodePath}`); - } else { - console.warn(`No bytecode found for contract: ${name}`); - } + const bytecodePath = join(artifactsDir, `${contractName}.bin`); + writeFileSync(bytecodePath, (contract as any).evm.bytecode.object); + console.log(`Bytecode saved to ${bytecodePath}`); } } } catch (error) { @@ -9971,9 +9991,10 @@ const compileContract = async ( }; const solidityFilePath: string = './contracts/Storage.sol'; -const outputDir: string = './artifacts/'; +const abiDir: string = './abis'; +const artifactsDir: string = './artifacts'; -compileContract(solidityFilePath, outputDir); +compileContract(solidityFilePath, abiDir, artifactsDir); ``` To compile your contract: @@ -9982,17 +10003,23 @@ To compile your contract: npm run compile ``` -After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.polkavm` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. +After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. ## Deploy the Contract Create a new file at `src/deploy.ts` for handling contract deployment: ```typescript title="src/deploy.ts" -import { readFileSync } from 'fs'; -import { join } from 'path'; -import { createWallet } from './createWallet'; -import { publicClient } from './createClient'; +import { existsSync, readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import { createWallet } from './createWallet.ts'; +import { publicClient } from './createClient.ts'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const ABIS_DIR = join(__dirname, '../abis'); +const ARTIFACTS_DIR = join(__dirname, '../artifacts'); const deployContract = async ( contractName: string, @@ -10001,16 +10028,20 @@ const deployContract = async ( try { console.log(`Deploying ${contractName}...`); + const abiPath = join(ABIS_DIR, `${contractName}.json`); + const bytecodePath = join(ARTIFACTS_DIR, `${contractName}.bin`); + + if (!existsSync(abiPath) || !existsSync(bytecodePath)) { + throw new Error( + `Missing artifacts for ${contractName}. Try running "npm run compile" first.` + ); + } + // Read contract artifacts const abi = JSON.parse( - readFileSync( - join(__dirname, '../artifacts', `${contractName}.json`), - 'utf8' - ) + readFileSync(abiPath, 'utf8') ); - const bytecode = `0x${readFileSync( - join(__dirname, '../artifacts', `${contractName}.polkavm`) - ).toString('hex')}` as `0x${string}`; + const bytecode = `0x${readFileSync(bytecodePath, 'utf8').trim()}` as `0x${string}`; // Create wallet const wallet = createWallet(privateKey); @@ -10056,13 +10087,17 @@ If everything is successful, you will see the address of your deployed contract Create a new file at `src/interact.ts` for interacting with your deployed contract: ```typescript title="src/interact.ts" -import { publicClient } from './createClient'; -import { createWallet } from './createWallet'; import { readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import { publicClient } from './createClient.ts'; +import { createWallet } from './createWallet.ts'; -const STORAGE_ABI = JSON.parse( - readFileSync('./artifacts/Storage.json', 'utf8') -); +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const ABI_PATH = join(__dirname, '../abis/Storage.json'); + +const STORAGE_ABI = JSON.parse(readFileSync(ABI_PATH, 'utf8')); const interactWithStorage = async ( contractAddress: `0x${string}`, @@ -10107,7 +10142,6 @@ const PRIVATE_KEY = 'INSERT_PRIVATE_KEY'; const CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS'; interactWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY); - ``` Ensure to replace `INSERT_PRIVATE_KEY` and `INSERT_CONTRACT_ADDRESS` with the proper values. diff --git a/.ai/categories/tooling.md b/.ai/categories/tooling.md index d5f748831..609e2c9fc 100644 --- a/.ai/categories/tooling.md +++ b/.ai/categories/tooling.md @@ -11644,8 +11644,6 @@ Page Title: viem for Polkadot Hub Smart Contracts # viem -!!! smartcontract "PolkaVM Preview Release" - PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction [viem](https://viem.sh/){target=\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub. @@ -11675,13 +11673,13 @@ viem-project/ │ └── interact.ts ├── contracts/ │ └── Storage.sol +├── abis/ +│ └── Storage.json └── artifacts/ - ├── Storage.json - └── Storage.polkavm + └── Storage.bin ``` -## Set Up the Project - +## Set Up the Proje First, create a new folder and initialize your project: ```bash @@ -11692,11 +11690,11 @@ npm init -y ## Install Dependencies -Install viem along with other necessary dependencies, including [@parity/resolc](https://www.npmjs.com/package/@parity/resolc){target=\_blank}, which enables to compile smart contracts to [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\_blank} bytecode: +Install viem along with other necessary dependencies, including [`solc`](https://www.npmjs.com/package/solc){target=\_blank}, which enables to compile smart contracts EVM bytecode: ```bash # Install viem and resolc -npm install viem @parity/resolc +npm install viem solc # Install TypeScript and development dependencies npm install --save-dev typescript ts-node @types/node @@ -11799,7 +11797,7 @@ After setting up the [Public Client](https://viem.sh/docs/clients/public#public- ```js title="src/fetchLastBlock.ts" import { createPublicClient, http } from 'viem'; - const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); + const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready // Configure the Polkadot Hub chain const polkadotHubTestnet = { @@ -11813,7 +11811,7 @@ After setting up the [Public Client](https://viem.sh/docs/clients/public#public- }, rpcUrls: { default: { - http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], + http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready }, }, } as const; @@ -11916,60 +11914,82 @@ contract Storage { ## Compile the Contract -!!! note "Contracts Code Blob Size Disclaimer" - The maximum contract code blob size on Polkadot Hub networks is _100 kilobytes_, significantly larger than Ethereum’s EVM limit of 24 kilobytes. - - For detailed comparisons and migration guidelines, see the [EVM vs. PolkaVM](/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/#current-memory-limits){target=\_blank} documentation page. - Create a new file at `src/compile.ts` for handling contract compilation: ```typescript title="src/compile.ts" -import { compile } from '@parity/resolc'; -import { readFileSync, writeFileSync } from 'fs'; +import solc from 'solc'; +import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'; import { basename, join } from 'path'; -const compileContract = async ( +const ensureDir = (dirPath: string): void => { + if (!existsSync(dirPath)) { + mkdirSync(dirPath, { recursive: true }); + } +}; + +const compileContract = ( solidityFilePath: string, - outputDir: string -): Promise => { + abiDir: string, + artifactsDir: string +): void => { try { // Read the Solidity file const source: string = readFileSync(solidityFilePath, 'utf8'); - - // Construct the input object for the compiler - const input: Record = { - [basename(solidityFilePath)]: { content: source }, + const fileName: string = basename(solidityFilePath); + + // Construct the input object for the Solidity compiler + const input = { + language: 'Solidity', + sources: { + [fileName]: { + content: source, + }, + }, + settings: { + outputSelection: { + '*': { + '*': ['abi', 'evm.bytecode'], + }, + }, + }, }; - - console.log(`Compiling contract: ${basename(solidityFilePath)}...`); - + + console.log(`Compiling contract: ${fileName}...`); + // Compile the contract - const out = await compile(input); - - for (const contracts of Object.values(out.contracts)) { - for (const [name, contract] of Object.entries(contracts)) { - console.log(`Compiled contract: ${name}`); - + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + // Check for errors + if (output.errors) { + const errors = output.errors.filter((error: any) => error.severity === 'error'); + if (errors.length > 0) { + console.error('Compilation errors:'); + errors.forEach((err: any) => console.error(err.formattedMessage)); + return; + } + // Show warnings + const warnings = output.errors.filter((error: any) => error.severity === 'warning'); + warnings.forEach((warn: any) => console.warn(warn.formattedMessage)); + } + + // Ensure output directories exist + ensureDir(abiDir); + ensureDir(artifactsDir); + + // Process compiled contracts + for (const [sourceFile, contracts] of Object.entries(output.contracts)) { + for (const [contractName, contract] of Object.entries(contracts as any)) { + console.log(`Compiled contract: ${contractName}`); + // Write the ABI - const abiPath = join(outputDir, `${name}.json`); - writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + const abiPath = join(abiDir, `${contractName}.json`); + writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2)); console.log(`ABI saved to ${abiPath}`); - + // Write the bytecode - if ( - contract.evm && - contract.evm.bytecode && - contract.evm.bytecode.object - ) { - const bytecodePath = join(outputDir, `${name}.polkavm`); - writeFileSync( - bytecodePath, - Buffer.from(contract.evm.bytecode.object, 'hex') - ); - console.log(`Bytecode saved to ${bytecodePath}`); - } else { - console.warn(`No bytecode found for contract: ${name}`); - } + const bytecodePath = join(artifactsDir, `${contractName}.bin`); + writeFileSync(bytecodePath, (contract as any).evm.bytecode.object); + console.log(`Bytecode saved to ${bytecodePath}`); } } } catch (error) { @@ -11978,9 +11998,10 @@ const compileContract = async ( }; const solidityFilePath: string = './contracts/Storage.sol'; -const outputDir: string = './artifacts/'; +const abiDir: string = './abis'; +const artifactsDir: string = './artifacts'; -compileContract(solidityFilePath, outputDir); +compileContract(solidityFilePath, abiDir, artifactsDir); ``` To compile your contract: @@ -11989,17 +12010,23 @@ To compile your contract: npm run compile ``` -After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.polkavm` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. +After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. ## Deploy the Contract Create a new file at `src/deploy.ts` for handling contract deployment: ```typescript title="src/deploy.ts" -import { readFileSync } from 'fs'; -import { join } from 'path'; -import { createWallet } from './createWallet'; -import { publicClient } from './createClient'; +import { existsSync, readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import { createWallet } from './createWallet.ts'; +import { publicClient } from './createClient.ts'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const ABIS_DIR = join(__dirname, '../abis'); +const ARTIFACTS_DIR = join(__dirname, '../artifacts'); const deployContract = async ( contractName: string, @@ -12008,16 +12035,20 @@ const deployContract = async ( try { console.log(`Deploying ${contractName}...`); + const abiPath = join(ABIS_DIR, `${contractName}.json`); + const bytecodePath = join(ARTIFACTS_DIR, `${contractName}.bin`); + + if (!existsSync(abiPath) || !existsSync(bytecodePath)) { + throw new Error( + `Missing artifacts for ${contractName}. Try running "npm run compile" first.` + ); + } + // Read contract artifacts const abi = JSON.parse( - readFileSync( - join(__dirname, '../artifacts', `${contractName}.json`), - 'utf8' - ) + readFileSync(abiPath, 'utf8') ); - const bytecode = `0x${readFileSync( - join(__dirname, '../artifacts', `${contractName}.polkavm`) - ).toString('hex')}` as `0x${string}`; + const bytecode = `0x${readFileSync(bytecodePath, 'utf8').trim()}` as `0x${string}`; // Create wallet const wallet = createWallet(privateKey); @@ -12063,13 +12094,17 @@ If everything is successful, you will see the address of your deployed contract Create a new file at `src/interact.ts` for interacting with your deployed contract: ```typescript title="src/interact.ts" -import { publicClient } from './createClient'; -import { createWallet } from './createWallet'; import { readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import { publicClient } from './createClient.ts'; +import { createWallet } from './createWallet.ts'; -const STORAGE_ABI = JSON.parse( - readFileSync('./artifacts/Storage.json', 'utf8') -); +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const ABI_PATH = join(__dirname, '../abis/Storage.json'); + +const STORAGE_ABI = JSON.parse(readFileSync(ABI_PATH, 'utf8')); const interactWithStorage = async ( contractAddress: `0x${string}`, @@ -12114,7 +12149,6 @@ const PRIVATE_KEY = 'INSERT_PRIVATE_KEY'; const CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS'; interactWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY); - ``` Ensure to replace `INSERT_PRIVATE_KEY` and `INSERT_CONTRACT_ADDRESS` with the proper values. diff --git a/.ai/pages/smart-contracts-libraries-viem.md b/.ai/pages/smart-contracts-libraries-viem.md index 25ab8039d..5725beed9 100644 --- a/.ai/pages/smart-contracts-libraries-viem.md +++ b/.ai/pages/smart-contracts-libraries-viem.md @@ -7,8 +7,6 @@ url: https://docs.polkadot.com/smart-contracts/libraries/viem/ # viem -!!! smartcontract "PolkaVM Preview Release" - PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction [viem](https://viem.sh/){target=\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub. @@ -38,13 +36,13 @@ viem-project/ │ └── interact.ts ├── contracts/ │ └── Storage.sol +├── abis/ +│ └── Storage.json └── artifacts/ - ├── Storage.json - └── Storage.polkavm + └── Storage.bin ``` -## Set Up the Project - +## Set Up the Proje First, create a new folder and initialize your project: ```bash @@ -55,11 +53,11 @@ npm init -y ## Install Dependencies -Install viem along with other necessary dependencies, including [@parity/resolc](https://www.npmjs.com/package/@parity/resolc){target=\_blank}, which enables to compile smart contracts to [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\_blank} bytecode: +Install viem along with other necessary dependencies, including [`solc`](https://www.npmjs.com/package/solc){target=\_blank}, which enables to compile smart contracts EVM bytecode: ```bash # Install viem and resolc -npm install viem @parity/resolc +npm install viem solc # Install TypeScript and development dependencies npm install --save-dev typescript ts-node @types/node @@ -162,7 +160,7 @@ After setting up the [Public Client](https://viem.sh/docs/clients/public#public- ```js title="src/fetchLastBlock.ts" import { createPublicClient, http } from 'viem'; - const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); + const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready // Configure the Polkadot Hub chain const polkadotHubTestnet = { @@ -176,7 +174,7 @@ After setting up the [Public Client](https://viem.sh/docs/clients/public#public- }, rpcUrls: { default: { - http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], + http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready }, }, } as const; @@ -279,60 +277,82 @@ contract Storage { ## Compile the Contract -!!! note "Contracts Code Blob Size Disclaimer" - The maximum contract code blob size on Polkadot Hub networks is _100 kilobytes_, significantly larger than Ethereum’s EVM limit of 24 kilobytes. - - For detailed comparisons and migration guidelines, see the [EVM vs. PolkaVM](/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/#current-memory-limits){target=\_blank} documentation page. - Create a new file at `src/compile.ts` for handling contract compilation: ```typescript title="src/compile.ts" -import { compile } from '@parity/resolc'; -import { readFileSync, writeFileSync } from 'fs'; +import solc from 'solc'; +import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'; import { basename, join } from 'path'; -const compileContract = async ( +const ensureDir = (dirPath: string): void => { + if (!existsSync(dirPath)) { + mkdirSync(dirPath, { recursive: true }); + } +}; + +const compileContract = ( solidityFilePath: string, - outputDir: string -): Promise => { + abiDir: string, + artifactsDir: string +): void => { try { // Read the Solidity file const source: string = readFileSync(solidityFilePath, 'utf8'); - - // Construct the input object for the compiler - const input: Record = { - [basename(solidityFilePath)]: { content: source }, + const fileName: string = basename(solidityFilePath); + + // Construct the input object for the Solidity compiler + const input = { + language: 'Solidity', + sources: { + [fileName]: { + content: source, + }, + }, + settings: { + outputSelection: { + '*': { + '*': ['abi', 'evm.bytecode'], + }, + }, + }, }; - - console.log(`Compiling contract: ${basename(solidityFilePath)}...`); - + + console.log(`Compiling contract: ${fileName}...`); + // Compile the contract - const out = await compile(input); - - for (const contracts of Object.values(out.contracts)) { - for (const [name, contract] of Object.entries(contracts)) { - console.log(`Compiled contract: ${name}`); - + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + // Check for errors + if (output.errors) { + const errors = output.errors.filter((error: any) => error.severity === 'error'); + if (errors.length > 0) { + console.error('Compilation errors:'); + errors.forEach((err: any) => console.error(err.formattedMessage)); + return; + } + // Show warnings + const warnings = output.errors.filter((error: any) => error.severity === 'warning'); + warnings.forEach((warn: any) => console.warn(warn.formattedMessage)); + } + + // Ensure output directories exist + ensureDir(abiDir); + ensureDir(artifactsDir); + + // Process compiled contracts + for (const [sourceFile, contracts] of Object.entries(output.contracts)) { + for (const [contractName, contract] of Object.entries(contracts as any)) { + console.log(`Compiled contract: ${contractName}`); + // Write the ABI - const abiPath = join(outputDir, `${name}.json`); - writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + const abiPath = join(abiDir, `${contractName}.json`); + writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2)); console.log(`ABI saved to ${abiPath}`); - + // Write the bytecode - if ( - contract.evm && - contract.evm.bytecode && - contract.evm.bytecode.object - ) { - const bytecodePath = join(outputDir, `${name}.polkavm`); - writeFileSync( - bytecodePath, - Buffer.from(contract.evm.bytecode.object, 'hex') - ); - console.log(`Bytecode saved to ${bytecodePath}`); - } else { - console.warn(`No bytecode found for contract: ${name}`); - } + const bytecodePath = join(artifactsDir, `${contractName}.bin`); + writeFileSync(bytecodePath, (contract as any).evm.bytecode.object); + console.log(`Bytecode saved to ${bytecodePath}`); } } } catch (error) { @@ -341,9 +361,10 @@ const compileContract = async ( }; const solidityFilePath: string = './contracts/Storage.sol'; -const outputDir: string = './artifacts/'; +const abiDir: string = './abis'; +const artifactsDir: string = './artifacts'; -compileContract(solidityFilePath, outputDir); +compileContract(solidityFilePath, abiDir, artifactsDir); ``` To compile your contract: @@ -352,17 +373,23 @@ To compile your contract: npm run compile ``` -After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.polkavm` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. +After executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub. ## Deploy the Contract Create a new file at `src/deploy.ts` for handling contract deployment: ```typescript title="src/deploy.ts" -import { readFileSync } from 'fs'; -import { join } from 'path'; -import { createWallet } from './createWallet'; -import { publicClient } from './createClient'; +import { existsSync, readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import { createWallet } from './createWallet.ts'; +import { publicClient } from './createClient.ts'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const ABIS_DIR = join(__dirname, '../abis'); +const ARTIFACTS_DIR = join(__dirname, '../artifacts'); const deployContract = async ( contractName: string, @@ -371,16 +398,20 @@ const deployContract = async ( try { console.log(`Deploying ${contractName}...`); + const abiPath = join(ABIS_DIR, `${contractName}.json`); + const bytecodePath = join(ARTIFACTS_DIR, `${contractName}.bin`); + + if (!existsSync(abiPath) || !existsSync(bytecodePath)) { + throw new Error( + `Missing artifacts for ${contractName}. Try running "npm run compile" first.` + ); + } + // Read contract artifacts const abi = JSON.parse( - readFileSync( - join(__dirname, '../artifacts', `${contractName}.json`), - 'utf8' - ) + readFileSync(abiPath, 'utf8') ); - const bytecode = `0x${readFileSync( - join(__dirname, '../artifacts', `${contractName}.polkavm`) - ).toString('hex')}` as `0x${string}`; + const bytecode = `0x${readFileSync(bytecodePath, 'utf8').trim()}` as `0x${string}`; // Create wallet const wallet = createWallet(privateKey); @@ -426,13 +457,17 @@ If everything is successful, you will see the address of your deployed contract Create a new file at `src/interact.ts` for interacting with your deployed contract: ```typescript title="src/interact.ts" -import { publicClient } from './createClient'; -import { createWallet } from './createWallet'; import { readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; +import { publicClient } from './createClient.ts'; +import { createWallet } from './createWallet.ts'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const ABI_PATH = join(__dirname, '../abis/Storage.json'); -const STORAGE_ABI = JSON.parse( - readFileSync('./artifacts/Storage.json', 'utf8') -); +const STORAGE_ABI = JSON.parse(readFileSync(ABI_PATH, 'utf8')); const interactWithStorage = async ( contractAddress: `0x${string}`, @@ -477,7 +512,6 @@ const PRIVATE_KEY = 'INSERT_PRIVATE_KEY'; const CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS'; interactWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY); - ``` Ensure to replace `INSERT_PRIVATE_KEY` and `INSERT_CONTRACT_ADDRESS` with the proper values. diff --git a/.ai/site-index.json b/.ai/site-index.json index 66fe0f3ff..18be5c994 100644 --- a/.ai/site-index.json +++ b/.ai/site-index.json @@ -8564,7 +8564,7 @@ ], "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-libraries-viem.md", "html_url": "https://docs.polkadot.com/smart-contracts/libraries/viem/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "preview": "[viem](https://viem.sh/){target=\\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub.", "outline": [ { "depth": 2, @@ -8583,8 +8583,8 @@ }, { "depth": 2, - "title": "Set Up the Project", - "anchor": "set-up-the-project" + "title": "Set Up the Proje", + "anchor": "set-up-the-proje" }, { "depth": 2, @@ -8638,12 +8638,12 @@ } ], "stats": { - "chars": 16600, - "words": 1940, + "chars": 17568, + "words": 2024, "headings": 14, - "estimated_token_count_total": 3891 + "estimated_token_count_total": 4177 }, - "hash": "sha256:e27657e4e4a14fe86f424b96631946ec36fb90d277e6010b6cbd64c4769aba8a", + "hash": "sha256:f671e04fcab3c9af17f4dff8ffd4c6952c42b8e7397c30a1e0e11761e771cc31", "token_estimator": "heuristic-v1" }, { diff --git a/llms-full.jsonl b/llms-full.jsonl index 643cef3d9..717c50ccb 100644 --- a/llms-full.jsonl +++ b/llms-full.jsonl @@ -1122,20 +1122,20 @@ {"page_id": "smart-contracts-libraries-ethers-js", "page_title": "Deploy Contracts to Polkadot Hub with Ethers.js", "index": 10, "depth": 2, "title": "Deploy the Compiled Contract", "anchor": "deploy-the-compiled-contract", "start_char": 8904, "end_char": 16591, "estimated_token_count": 1604, "token_estimator": "heuristic-v1", "text": "## Deploy the Compiled Contract\n\nTo deploy your compiled contract to Polkadot Hub, you'll need a wallet with a private key to sign the deployment transaction.\n\nYou can create a `deploy.js` script in the root of your project to achieve this. The deployment script can be divided into key components:\n\n1. Set up the required imports and utilities:\n\n ```js title=\"scripts/deploy.js\"\n // Deploy an EVM-compatible smart contract using ethers.js\n const { writeFileSync, existsSync, readFileSync } = require('fs');\n const { join } = require('path');\n const { ethers, JsonRpcProvider } = require('ethers');\n\n const codegenDir = join(__dirname);\n ```\n\n2. Create a provider to connect to Polkadot Hub:\n\n ```js title=\"scripts/deploy.js\"\n\n // Creates an Ethereum provider with specified RPC URL and chain details\n const createProvider = (rpcUrl, chainId, chainName) => {\n const provider = new JsonRpcProvider(rpcUrl, {\n chainId: chainId,\n name: chainName,\n });\n return provider;\n };\n ```\n \n3. Set up functions to read contract artifacts:\n\n ```js title=\"scripts/deploy.js\"\n // Reads and parses the ABI file for a given contract\n const getAbi = (contractName) => {\n try {\n return JSON.parse(\n readFileSync(join(codegenDir, `${contractName}.json`), 'utf8'),\n );\n } catch (error) {\n console.error(\n `Could not find ABI for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n };\n\n // Reads the compiled bytecode for a given contract\n const getByteCode = (contractName) => {\n try {\n const bytecodePath = join(\n codegenDir,\n '../contracts',\n `${contractName}.polkavm`,\n );\n return `0x${readFileSync(bytecodePath).toString('hex')}`;\n } catch (error) {\n console.error(\n `Could not find bytecode for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n };\n ```\n\n4. Create the main deployment function:\n\n ```js title=\"scripts/deploy.js\"\n\n const deployContract = async (contractName, mnemonic, providerConfig) => {\n console.log(`Deploying ${contractName}...`);\n\n try {\n // Step 1: Set up provider and wallet\n const provider = createProvider(\n providerConfig.rpc,\n providerConfig.chainId,\n providerConfig.name,\n );\n const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic);\n const wallet = walletMnemonic.connect(provider);\n\n // Step 2: Create and deploy the contract\n const factory = new ethers.ContractFactory(\n getAbi(contractName),\n getByteCode(contractName),\n wallet,\n );\n const contract = await factory.deploy();\n await contract.waitForDeployment();\n\n // Step 3: Save deployment information\n const address = await contract.getAddress();\n console.log(`Contract ${contractName} deployed at: ${address}`);\n\n const addressesFile = join(codegenDir, 'contract-address.json');\n const addresses = existsSync(addressesFile)\n ? JSON.parse(readFileSync(addressesFile, 'utf8'))\n : {};\n addresses[contractName] = address;\n writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8');\n } catch (error) {\n console.error(`Failed to deploy contract ${contractName}:`, error);\n }\n };\n ```\n\n5. Configure and execute the deployment:\n\n ```js title=\"scripts/deploy.js\"\n const providerConfig = {\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n name: 'polkadot-hub-testnet',\n };\n\n const mnemonic = 'INSERT_MNEMONIC';\n\n deployContract('Storage', mnemonic, providerConfig);\n ```\n\n !!! note\n A mnemonic (seed phrase) is a series of words that can generate multiple private keys and their corresponding addresses. It's used here to derive the wallet that will sign and pay for the deployment transaction. **Always keep your mnemonic secure and never share it publicly**.\n\n Ensure to replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic.\n\n??? code \"View complete script\"\n\n ```js title=\"scripts/deploy.js\"\n // Deploy an EVM-compatible smart contract using ethers.js\n const { writeFileSync, existsSync, readFileSync } = require('fs');\n const { join } = require('path');\n const { ethers, JsonRpcProvider } = require('ethers');\n\n const codegenDir = join(__dirname);\n\n // Creates an Ethereum provider with specified RPC URL and chain details\n const createProvider = (rpcUrl, chainId, chainName) => {\n const provider = new JsonRpcProvider(rpcUrl, {\n chainId: chainId,\n name: chainName,\n });\n return provider;\n };\n\n // Reads and parses the ABI file for a given contract\n const getAbi = (contractName) => {\n try {\n return JSON.parse(\n readFileSync(join(codegenDir, `${contractName}.json`), 'utf8'),\n );\n } catch (error) {\n console.error(\n `Could not find ABI for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n };\n\n // Reads the compiled bytecode for a given contract\n const getByteCode = (contractName) => {\n try {\n const bytecodePath = join(\n codegenDir,\n '../contracts',\n `${contractName}.polkavm`,\n );\n return `0x${readFileSync(bytecodePath).toString('hex')}`;\n } catch (error) {\n console.error(\n `Could not find bytecode for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n };\n\n const deployContract = async (contractName, mnemonic, providerConfig) => {\n console.log(`Deploying ${contractName}...`);\n\n try {\n // Step 1: Set up provider and wallet\n const provider = createProvider(\n providerConfig.rpc,\n providerConfig.chainId,\n providerConfig.name,\n );\n const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic);\n const wallet = walletMnemonic.connect(provider);\n\n // Step 2: Create and deploy the contract\n const factory = new ethers.ContractFactory(\n getAbi(contractName),\n getByteCode(contractName),\n wallet,\n );\n const contract = await factory.deploy();\n await contract.waitForDeployment();\n\n // Step 3: Save deployment information\n const address = await contract.getAddress();\n console.log(`Contract ${contractName} deployed at: ${address}`);\n\n const addressesFile = join(codegenDir, 'contract-address.json');\n const addresses = existsSync(addressesFile)\n ? JSON.parse(readFileSync(addressesFile, 'utf8'))\n : {};\n addresses[contractName] = address;\n writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8');\n } catch (error) {\n console.error(`Failed to deploy contract ${contractName}:`, error);\n }\n };\n\n const providerConfig = {\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n name: 'polkadot-hub-testnet',\n };\n\n const mnemonic = 'INSERT_MNEMONIC';\n\n deployContract('Storage', mnemonic, providerConfig);\n\n ```\n\nTo run the script, execute the following command:\n\n```bash\nnode deploy\n```\n\nAfter running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions."} {"page_id": "smart-contracts-libraries-ethers-js", "page_title": "Deploy Contracts to Polkadot Hub with Ethers.js", "index": 11, "depth": 2, "title": "Interact with the Contract", "anchor": "interact-with-the-contract", "start_char": 16591, "end_char": 19852, "estimated_token_count": 712, "token_estimator": "heuristic-v1", "text": "## Interact with the Contract\n\nOnce the contract is deployed, you can interact with it by calling its functions. For example, to set a number, read it and then modify that number by its double, you can create a file named `checkStorage.js` in the root of your project and add the following code:\n\n```js title=\"scripts/checkStorage.js\"\nconst { ethers } = require('ethers');\nconst { readFileSync } = require('fs');\nconst { join } = require('path');\n\nconst createProvider = (providerConfig) => {\n return new ethers.JsonRpcProvider(providerConfig.rpc, {\n chainId: providerConfig.chainId,\n name: providerConfig.name,\n });\n};\n\nconst createWallet = (mnemonic, provider) => {\n return ethers.Wallet.fromPhrase(mnemonic).connect(provider);\n};\n\nconst loadContractAbi = (contractName, directory = __dirname) => {\n const contractPath = join(directory, `${contractName}.json`);\n const contractJson = JSON.parse(readFileSync(contractPath, 'utf8'));\n return contractJson.abi || contractJson; // Depending on JSON structure\n};\n\nconst createContract = (contractAddress, abi, wallet) => {\n return new ethers.Contract(contractAddress, abi, wallet);\n};\n\nconst interactWithStorageContract = async (\n contractName,\n contractAddress,\n mnemonic,\n providerConfig,\n numberToSet,\n) => {\n try {\n console.log(`Setting new number in Storage contract: ${numberToSet}`);\n\n // Create provider and wallet\n const provider = createProvider(providerConfig);\n const wallet = createWallet(mnemonic, provider);\n\n // Load the contract ABI and create the contract instance\n const abi = loadContractAbi(contractName);\n const contract = createContract(contractAddress, abi, wallet);\n\n // Send a transaction to set the stored number\n const tx1 = await contract.setNumber(numberToSet);\n await tx1.wait(); // Wait for the transaction to be mined\n console.log(`Number successfully set to ${numberToSet}`);\n\n // Retrieve the updated number\n const storedNumber = await contract.storedNumber();\n console.log(`Retrieved stored number:`, storedNumber.toString());\n\n // Send a transaction to set the stored number\n const tx2 = await contract.setNumber(numberToSet * 2);\n await tx2.wait(); // Wait for the transaction to be mined\n console.log(`Number successfully set to ${numberToSet * 2}`);\n\n // Retrieve the updated number\n const updatedNumber = await contract.storedNumber();\n console.log(`Retrieved stored number:`, updatedNumber.toString());\n } catch (error) {\n console.error('Error interacting with Storage contract:', error.message);\n }\n};\n\nconst providerConfig = {\n name: 'asset-hub-smart-contracts',\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n};\n\nconst mnemonic = 'INSERT_MNEMONIC';\nconst contractName = 'Storage';\nconst contractAddress = 'INSERT_CONTRACT_ADDRESS';\nconst newNumber = 42;\n\ninteractWithStorageContract(\n contractName,\n contractAddress,\n mnemonic,\n providerConfig,\n newNumber,\n);\n\n```\n\nEnsure you replace the `INSERT_MNEMONIC`, `INSERT_CONTRACT_ADDRESS`, and `INSERT_ADDRESS_TO_CHECK` placeholders with actual values. Also, ensure the contract ABI file (`Storage.json`) is correctly referenced.\n\nTo interact with the contract, run:\n\n```bash\nnode checkStorage\n```"} {"page_id": "smart-contracts-libraries-ethers-js", "page_title": "Deploy Contracts to Polkadot Hub with Ethers.js", "index": 12, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 19852, "end_char": 20457, "estimated_token_count": 155, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you have the foundational knowledge to use Ethers.js with Polkadot Hub, you can:\n\n- **Dive into Ethers.js utilities**: Discover additional Ethers.js features, such as wallet management, signing messages, etc.\n- **Implement batch transactions**: Use Ethers.js to execute batch transactions for efficient multi-step contract interactions.\n- **Build scalable applications**: Combine Ethers.js with frameworks like [`Next.js`](https://nextjs.org/docs){target=\\_blank} or [`Node.js`](https://nodejs.org/en){target=\\_blank} to create full-stack decentralized applications (dApps)."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 178, "end_char": 455, "estimated_token_count": 56, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[viem](https://viem.sh/){target=\\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 455, "end_char": 811, "estimated_token_count": 110, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore getting started, ensure you have the following installed:\n\n- **Node.js**: v22.13.1 or later, check the [Node.js installation guide](https://nodejs.org/en/download/current/){target=\\_blank}.\n- **npm**: v6.13.4 or later (comes bundled with Node.js).\n- **Solidity**: This guide uses Solidity `^0.8.9` for smart contract development."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 2, "depth": 2, "title": "Project Structure", "anchor": "project-structure", "start_char": 811, "end_char": 1231, "estimated_token_count": 119, "token_estimator": "heuristic-v1", "text": "## Project Structure\n\nThis project organizes contracts, scripts, and compiled artifacts for easy development and deployment.\n\n```text\nviem-project/\n├── package.json\n├── tsconfig.json\n├── src/\n│ ├── chainConfig.ts\n│ ├── createClient.ts\n│ ├── createWallet.ts\n│ ├── compile.ts\n│ ├── deploy.ts\n│ └── interact.ts\n├── contracts/\n│ └── Storage.sol\n└── artifacts/\n ├── Storage.json\n └── Storage.polkavm\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 3, "depth": 2, "title": "Set Up the Project", "anchor": "set-up-the-project", "start_char": 1231, "end_char": 1371, "estimated_token_count": 36, "token_estimator": "heuristic-v1", "text": "## Set Up the Project\n\nFirst, create a new folder and initialize your project:\n\n```bash\nmkdir viem-project\ncd viem-project\nnpm init -y\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 4, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 1371, "end_char": 1837, "estimated_token_count": 117, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall viem along with other necessary dependencies, including [@parity/resolc](https://www.npmjs.com/package/@parity/resolc){target=\\_blank}, which enables to compile smart contracts to [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\\_blank} bytecode:\n\n```bash\n# Install viem and resolc\nnpm install viem @parity/resolc\n\n# Install TypeScript and development dependencies\nnpm install --save-dev typescript ts-node @types/node\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 5, "depth": 2, "title": "Initialize Project", "anchor": "initialize-project", "start_char": 1837, "end_char": 2347, "estimated_token_count": 137, "token_estimator": "heuristic-v1", "text": "## Initialize Project\n\nInitialize a TypeScript project by running the following command:\n\n```bash\nnpx tsc --init\n```\n\nAdd the following scripts to your `package.json` file to enable running TypeScript files:\n\n```json\n{\n \"scripts\": {\n \"client\": \"ts-node src/createClient.ts\",\n \"compile\": \"ts-node src/compile.ts\",\n \"deploy\": \"ts-node src/deploy.ts\",\n \"interact\": \"ts-node src/interact.ts\"\n },\n}\n```\n\nCreate a directory for your TypeScript source files:\n\n```bash\nmkdir src\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 6, "depth": 2, "title": "Set Up the Chain Configuration", "anchor": "set-up-the-chain-configuration", "start_char": 2347, "end_char": 3302, "estimated_token_count": 205, "token_estimator": "heuristic-v1", "text": "## Set Up the Chain Configuration\n\nThe first step is to set up the chain configuration. Create a new file at `src/chainConfig.ts`:\n\n```typescript title=\"src/chainConfig.ts\"\nimport { http } from 'viem';\n\nexport const TRANSPORT = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nexport const POLKADOT_HUB = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n```\n\nEnsure to replace `INSERT_RPC_URL`, `INSERT_CHAIN_ID`, `INSERT_CHAIN_NAME`, `INSERT_NETWORK_NAME`, `INSERT_CHAIN_DECIMALS`, `INSERT_CURRENCY_NAME`, and `INSERT_CURRENCY_SYMBOL` with the proper values. Check the [Connect to Polkadot](/smart-contracts/connect/){target=\\_blank} page for more information on the possible values."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 7, "depth": 2, "title": "Set Up the viem Client", "anchor": "set-up-the-viem-client", "start_char": 3302, "end_char": 5418, "estimated_token_count": 483, "token_estimator": "heuristic-v1", "text": "## Set Up the viem Client\n\nTo interact with the chain, you need to create a client that is used solely for reading data. To accomplish this, create a new file at `src/createClient.ts`:\n\n```typescript title=\"src/createClient.ts\"\nimport { createPublicClient, createWalletClient, http } from 'viem';\n\nconst transport = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create a public client for reading data\nexport const publicClient = createPublicClient({\n chain: assetHub,\n transport,\n});\n\n```\n\nAfter setting up the [Public Client](https://viem.sh/docs/clients/public#public-client){target=\\_blank}, you can begin querying the blockchain. Here's an example of fetching the latest block number:\n\n??? code \"Fetch Last Block code\"\n\n ```js title=\"src/fetchLastBlock.ts\"\n import { createPublicClient, http } from 'viem';\n\n const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io');\n\n // Configure the Polkadot Hub chain\n const polkadotHubTestnet = {\n id: 420420422,\n name: 'Polkadot Hub TestNet',\n network: 'polkadot-hub-testnet',\n nativeCurrency: {\n decimals: 18,\n name: 'PAS',\n symbol: 'PAS',\n },\n rpcUrls: {\n default: {\n http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'],\n },\n },\n } as const;\n\n // Create a public client for reading data\n export const publicClient = createPublicClient({\n chain: polkadotHubTestnet,\n transport,\n });\n\n const main = async () => {\n try {\n const block = await publicClient.getBlock();\n console.log('Last block: ' + block.number.toString());\n } catch (error: unknown) {\n console.error('Error connecting to Polkadot Hub TestNet: ' + error);\n }\n };\n\n main();\n ```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 8, "depth": 2, "title": "Set Up a Wallet", "anchor": "set-up-a-wallet", "start_char": 5418, "end_char": 6775, "estimated_token_count": 299, "token_estimator": "heuristic-v1", "text": "## Set Up a Wallet\n\nIn case you need to sign transactions, you will need to instantiate a [Wallet Client](https://viem.sh/docs/clients/wallet#wallet-client){target=\\_blank} object within your project. To do so, create `src/createWallet.ts`:\n\n```typescript title=\"src/createWallet.ts\"\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { createWalletClient, http } from 'viem';\n\nconst transport = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n public: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create a wallet client for writing data\nexport const createWallet = (privateKey: `0x${string}`) => {\n const account = privateKeyToAccount(privateKey);\n return createWalletClient({\n account,\n chain: assetHub,\n transport,\n });\n};\n```\n\n!!!note\n The wallet you import with your private key must have sufficient funds to pay for transaction fees when deploying contracts or interacting with them. Make sure to fund your wallet with the appropriate native tokens for the network you're connecting to."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 9, "depth": 2, "title": "Sample Smart Contract", "anchor": "sample-smart-contract", "start_char": 6775, "end_char": 7756, "estimated_token_count": 204, "token_estimator": "heuristic-v1", "text": "## Sample Smart Contract\n\nThis example demonstrates compiling a `Storage.sol` Solidity contract for deployment to Polkadot Hub. The contract's functionality stores a number and permits users to update it with a new value.\n\n```bash\nmkdir contracts artifacts\n```\n\nYou can use the following contract to interact with the blockchain. Paste the following contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n//SPDX-License-Identifier: MIT\n\n// Solidity files have to start with this pragma.\n// It will be used by the Solidity compiler to validate its version.\npragma solidity ^0.8.9;\n\ncontract Storage {\n // Public state variable to store a number\n uint256 public storedNumber;\n\n /**\n * Updates the stored number.\n *\n * The `public` modifier allows anyone to call this function.\n *\n * @param _newNumber - The new value to store.\n */\n function setNumber(uint256 _newNumber) public {\n storedNumber = _newNumber;\n }\n}\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 10, "depth": 2, "title": "Compile the Contract", "anchor": "compile-the-contract", "start_char": 7756, "end_char": 10480, "estimated_token_count": 621, "token_estimator": "heuristic-v1", "text": "## Compile the Contract\n\n!!! note \"Contracts Code Blob Size Disclaimer\"\n The maximum contract code blob size on Polkadot Hub networks is _100 kilobytes_, significantly larger than Ethereum’s EVM limit of 24 kilobytes.\n\n For detailed comparisons and migration guidelines, see the [EVM vs. PolkaVM](/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/#current-memory-limits){target=\\_blank} documentation page.\n\nCreate a new file at `src/compile.ts` for handling contract compilation:\n\n```typescript title=\"src/compile.ts\"\nimport { compile } from '@parity/resolc';\nimport { readFileSync, writeFileSync } from 'fs';\nimport { basename, join } from 'path';\n\nconst compileContract = async (\n solidityFilePath: string,\n outputDir: string\n): Promise => {\n try {\n // Read the Solidity file\n const source: string = readFileSync(solidityFilePath, 'utf8');\n\n // Construct the input object for the compiler\n const input: Record = {\n [basename(solidityFilePath)]: { content: source },\n };\n\n console.log(`Compiling contract: ${basename(solidityFilePath)}...`);\n\n // Compile the contract\n const out = await compile(input);\n\n for (const contracts of Object.values(out.contracts)) {\n for (const [name, contract] of Object.entries(contracts)) {\n console.log(`Compiled contract: ${name}`);\n\n // Write the ABI\n const abiPath = join(outputDir, `${name}.json`);\n writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n\n // Write the bytecode\n if (\n contract.evm &&\n contract.evm.bytecode &&\n contract.evm.bytecode.object\n ) {\n const bytecodePath = join(outputDir, `${name}.polkavm`);\n writeFileSync(\n bytecodePath,\n Buffer.from(contract.evm.bytecode.object, 'hex')\n );\n console.log(`Bytecode saved to ${bytecodePath}`);\n } else {\n console.warn(`No bytecode found for contract: ${name}`);\n }\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath: string = './contracts/Storage.sol';\nconst outputDir: string = './artifacts/';\n\ncompileContract(solidityFilePath, outputDir);\n```\n\nTo compile your contract:\n\n```bash\nnpm run compile\n```\n\nAfter executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.polkavm` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 11, "depth": 2, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 10480, "end_char": 12665, "estimated_token_count": 504, "token_estimator": "heuristic-v1", "text": "## Deploy the Contract\n\nCreate a new file at `src/deploy.ts` for handling contract deployment:\n\n```typescript title=\"src/deploy.ts\"\nimport { readFileSync } from 'fs';\nimport { join } from 'path';\nimport { createWallet } from './createWallet';\nimport { publicClient } from './createClient';\n\nconst deployContract = async (\n contractName: string,\n privateKey: `0x${string}`\n) => {\n try {\n console.log(`Deploying ${contractName}...`);\n\n // Read contract artifacts\n const abi = JSON.parse(\n readFileSync(\n join(__dirname, '../artifacts', `${contractName}.json`),\n 'utf8'\n )\n );\n const bytecode = `0x${readFileSync(\n join(__dirname, '../artifacts', `${contractName}.polkavm`)\n ).toString('hex')}` as `0x${string}`;\n\n // Create wallet\n const wallet = createWallet(privateKey);\n\n // Deploy contract\n const hash = await wallet.deployContract({\n abi,\n bytecode,\n args: [], // Add constructor arguments if needed\n });\n\n // Wait for deployment\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n const contractAddress = receipt.contractAddress;\n\n console.log(`Contract deployed at: ${contractAddress}`);\n return contractAddress;\n } catch (error) {\n console.error('Deployment failed:', error);\n throw error;\n }\n};\n\nconst privateKey = 'INSERT_PRIVATE_KEY';\ndeployContract('Storage', privateKey);\n```\n\nEnsure to replace `INSERT_PRIVATE_KEY` with the proper value. For further details on private key exportation, refer to the article [How to export an account's private key](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/){target=\\_blank}.\n\n!!! warning\n Never commit or share your private key. Exposed keys can lead to immediate theft of all associated funds. Use environment variables instead.\n\nTo deploy, run the following command:\n\n```bash\nnpm run deploy\n```\n\nIf everything is successful, you will see the address of your deployed contract displayed in the terminal. This address is unique to your contract on the network you defined in the chain configuration, and you'll need it for any future interactions with your contract."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 12, "depth": 2, "title": "Interact with the Contract", "anchor": "interact-with-the-contract", "start_char": 12665, "end_char": 14831, "estimated_token_count": 455, "token_estimator": "heuristic-v1", "text": "## Interact with the Contract\n\nCreate a new file at `src/interact.ts` for interacting with your deployed contract:\n\n```typescript title=\"src/interact.ts\"\nimport { publicClient } from './createClient';\nimport { createWallet } from './createWallet';\nimport { readFileSync } from 'fs';\n\nconst STORAGE_ABI = JSON.parse(\n readFileSync('./artifacts/Storage.json', 'utf8')\n);\n\nconst interactWithStorage = async (\n contractAddress: `0x${string}`,\n privateKey: `0x${string}`\n) => {\n try {\n const wallet = createWallet(privateKey);\n const currentNumber = await publicClient.readContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'storedNumber',\n args: [],\n });\n console.log(`Stored number: ${currentNumber}`);\n\n const newNumber = BigInt(42);\n const { request } = await publicClient.simulateContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'setNumber',\n args: [newNumber],\n account: wallet.account,\n });\n\n const hash = await wallet.writeContract(request);\n await publicClient.waitForTransactionReceipt({ hash });\n console.log(`Number updated to ${newNumber}`);\n\n const updatedNumber = await publicClient.readContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'storedNumber',\n args: [],\n });\n console.log('Updated stored number:', updatedNumber);\n } catch (error) {\n console.error('Interaction failed:', error);\n }\n};\n\nconst PRIVATE_KEY = 'INSERT_PRIVATE_KEY';\nconst CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS';\n\ninteractWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY);\n\n```\n\nEnsure to replace `INSERT_PRIVATE_KEY` and `INSERT_CONTRACT_ADDRESS` with the proper values.\n\nTo interact with the contract:\n\n```bash\nnpm run interact\n```\n\nFollowing a successful interaction, you will see the stored value before and after the transaction. The output will show the initial stored number (0 if you haven't modified it yet), confirm when the transaction to set the number to 42 is complete, and then display the updated stored number value. This demonstrates both reading from and writing to your smart contract."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 13, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 14831, "end_char": 16600, "estimated_token_count": 545, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you have the foundation for using viem with Polkadot Hub, consider exploring:\n\n
\n\n- External __Advanced viem Features__\n\n ---\n Explore viem's documentation:\n
    \n
  • [:octicons-arrow-right-24: Multi call](https://viem.sh/docs/contract/multicall#multicall){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Batch transactions](https://viem.sh/docs/clients/transports/http#batch-json-rpc){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Custom actions](https://viem.sh/docs/clients/custom#extending-with-actions-or-configuration){target=\\_blank}
  • \n
\n\n- External __Test Frameworks__\n\n ---\n\n Integrate viem with the following frameworks for comprehensive testing:\n
    \n
  • [:octicons-arrow-right-24: Hardhat](https://hardhat.org/){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Foundry](https://getfoundry.sh/){target=\\_blank}
  • \n
\n\n- External __Event Handling__\n\n ---\n\n Learn how to subscribe to and process contract events:\n
    \n
  • [:octicons-arrow-right-24: Event subscription](https://viem.sh/docs/actions/public/watchEvent#watchevent){target=\\_blank}
  • \n
\n\n- External __Building dApps__\n\n ---\n\n Combine viem the following technologies to create full-stack applications:\n
    \n
  • [:octicons-arrow-right-24: Next.js](https://nextjs.org/docs){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Node.js](https://nodejs.org/en){target=\\_blank}
  • \n
\n\n
"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 8, "end_char": 285, "estimated_token_count": 56, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[viem](https://viem.sh/){target=\\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 285, "end_char": 641, "estimated_token_count": 110, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore getting started, ensure you have the following installed:\n\n- **Node.js**: v22.13.1 or later, check the [Node.js installation guide](https://nodejs.org/en/download/current/){target=\\_blank}.\n- **npm**: v6.13.4 or later (comes bundled with Node.js).\n- **Solidity**: This guide uses Solidity `^0.8.9` for smart contract development."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 2, "depth": 2, "title": "Project Structure", "anchor": "project-structure", "start_char": 641, "end_char": 1067, "estimated_token_count": 125, "token_estimator": "heuristic-v1", "text": "## Project Structure\n\nThis project organizes contracts, scripts, and compiled artifacts for easy development and deployment.\n\n```text\nviem-project/\n├── package.json\n├── tsconfig.json\n├── src/\n│ ├── chainConfig.ts\n│ ├── createClient.ts\n│ ├── createWallet.ts\n│ ├── compile.ts\n│ ├── deploy.ts\n│ └── interact.ts\n├── contracts/\n│ └── Storage.sol\n├── abis/\n│ └── Storage.json\n└── artifacts/\n └── Storage.bin\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 3, "depth": 2, "title": "Set Up the Proje", "anchor": "set-up-the-proje", "start_char": 1067, "end_char": 1204, "estimated_token_count": 36, "token_estimator": "heuristic-v1", "text": "## Set Up the Proje\nFirst, create a new folder and initialize your project:\n\n```bash\nmkdir viem-project\ncd viem-project\nnpm init -y\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 4, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 1204, "end_char": 1577, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall viem along with other necessary dependencies, including [`solc`](https://www.npmjs.com/package/solc){target=\\_blank}, which enables to compile smart contracts EVM bytecode:\n\n```bash\n# Install viem and resolc\nnpm install viem solc\n\n# Install TypeScript and development dependencies\nnpm install --save-dev typescript ts-node @types/node\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 5, "depth": 2, "title": "Initialize Project", "anchor": "initialize-project", "start_char": 1577, "end_char": 2087, "estimated_token_count": 137, "token_estimator": "heuristic-v1", "text": "## Initialize Project\n\nInitialize a TypeScript project by running the following command:\n\n```bash\nnpx tsc --init\n```\n\nAdd the following scripts to your `package.json` file to enable running TypeScript files:\n\n```json\n{\n \"scripts\": {\n \"client\": \"ts-node src/createClient.ts\",\n \"compile\": \"ts-node src/compile.ts\",\n \"deploy\": \"ts-node src/deploy.ts\",\n \"interact\": \"ts-node src/interact.ts\"\n },\n}\n```\n\nCreate a directory for your TypeScript source files:\n\n```bash\nmkdir src\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 6, "depth": 2, "title": "Set Up the Chain Configuration", "anchor": "set-up-the-chain-configuration", "start_char": 2087, "end_char": 3042, "estimated_token_count": 205, "token_estimator": "heuristic-v1", "text": "## Set Up the Chain Configuration\n\nThe first step is to set up the chain configuration. Create a new file at `src/chainConfig.ts`:\n\n```typescript title=\"src/chainConfig.ts\"\nimport { http } from 'viem';\n\nexport const TRANSPORT = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nexport const POLKADOT_HUB = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n```\n\nEnsure to replace `INSERT_RPC_URL`, `INSERT_CHAIN_ID`, `INSERT_CHAIN_NAME`, `INSERT_NETWORK_NAME`, `INSERT_CHAIN_DECIMALS`, `INSERT_CURRENCY_NAME`, and `INSERT_CURRENCY_SYMBOL` with the proper values. Check the [Connect to Polkadot](/smart-contracts/connect/){target=\\_blank} page for more information on the possible values."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 7, "depth": 2, "title": "Set Up the viem Client", "anchor": "set-up-the-viem-client", "start_char": 3042, "end_char": 5250, "estimated_token_count": 505, "token_estimator": "heuristic-v1", "text": "## Set Up the viem Client\n\nTo interact with the chain, you need to create a client that is used solely for reading data. To accomplish this, create a new file at `src/createClient.ts`:\n\n```typescript title=\"src/createClient.ts\"\nimport { createPublicClient, createWalletClient, http } from 'viem';\n\nconst transport = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create a public client for reading data\nexport const publicClient = createPublicClient({\n chain: assetHub,\n transport,\n});\n\n```\n\nAfter setting up the [Public Client](https://viem.sh/docs/clients/public#public-client){target=\\_blank}, you can begin querying the blockchain. Here's an example of fetching the latest block number:\n\n??? code \"Fetch Last Block code\"\n\n ```js title=\"src/fetchLastBlock.ts\"\n import { createPublicClient, http } from 'viem';\n\n const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready\n\n // Configure the Polkadot Hub chain\n const polkadotHubTestnet = {\n id: 420420422,\n name: 'Polkadot Hub TestNet',\n network: 'polkadot-hub-testnet',\n nativeCurrency: {\n decimals: 18,\n name: 'PAS',\n symbol: 'PAS',\n },\n rpcUrls: {\n default: {\n http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready\n },\n },\n } as const;\n\n // Create a public client for reading data\n export const publicClient = createPublicClient({\n chain: polkadotHubTestnet,\n transport,\n });\n\n const main = async () => {\n try {\n const block = await publicClient.getBlock();\n console.log('Last block: ' + block.number.toString());\n } catch (error: unknown) {\n console.error('Error connecting to Polkadot Hub TestNet: ' + error);\n }\n };\n\n main();\n ```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 8, "depth": 2, "title": "Set Up a Wallet", "anchor": "set-up-a-wallet", "start_char": 5250, "end_char": 6607, "estimated_token_count": 299, "token_estimator": "heuristic-v1", "text": "## Set Up a Wallet\n\nIn case you need to sign transactions, you will need to instantiate a [Wallet Client](https://viem.sh/docs/clients/wallet#wallet-client){target=\\_blank} object within your project. To do so, create `src/createWallet.ts`:\n\n```typescript title=\"src/createWallet.ts\"\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { createWalletClient, http } from 'viem';\n\nconst transport = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n public: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create a wallet client for writing data\nexport const createWallet = (privateKey: `0x${string}`) => {\n const account = privateKeyToAccount(privateKey);\n return createWalletClient({\n account,\n chain: assetHub,\n transport,\n });\n};\n```\n\n!!!note\n The wallet you import with your private key must have sufficient funds to pay for transaction fees when deploying contracts or interacting with them. Make sure to fund your wallet with the appropriate native tokens for the network you're connecting to."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 9, "depth": 2, "title": "Sample Smart Contract", "anchor": "sample-smart-contract", "start_char": 6607, "end_char": 7588, "estimated_token_count": 204, "token_estimator": "heuristic-v1", "text": "## Sample Smart Contract\n\nThis example demonstrates compiling a `Storage.sol` Solidity contract for deployment to Polkadot Hub. The contract's functionality stores a number and permits users to update it with a new value.\n\n```bash\nmkdir contracts artifacts\n```\n\nYou can use the following contract to interact with the blockchain. Paste the following contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n//SPDX-License-Identifier: MIT\n\n// Solidity files have to start with this pragma.\n// It will be used by the Solidity compiler to validate its version.\npragma solidity ^0.8.9;\n\ncontract Storage {\n // Public state variable to store a number\n uint256 public storedNumber;\n\n /**\n * Updates the stored number.\n *\n * The `public` modifier allows anyone to call this function.\n *\n * @param _newNumber - The new value to store.\n */\n function setNumber(uint256 _newNumber) public {\n storedNumber = _newNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 10, "depth": 2, "title": "Compile the Contract", "anchor": "compile-the-contract", "start_char": 7588, "end_char": 10801, "estimated_token_count": 749, "token_estimator": "heuristic-v1", "text": "## Compile the Contract\n\nCreate a new file at `src/compile.ts` for handling contract compilation:\n\n```typescript title=\"src/compile.ts\"\nimport solc from 'solc';\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { basename, join } from 'path';\n\nconst ensureDir = (dirPath: string): void => {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n};\n\nconst compileContract = (\n solidityFilePath: string,\n abiDir: string,\n artifactsDir: string\n): void => {\n try {\n // Read the Solidity file\n const source: string = readFileSync(solidityFilePath, 'utf8');\n const fileName: string = basename(solidityFilePath);\n \n // Construct the input object for the Solidity compiler\n const input = {\n language: 'Solidity',\n sources: {\n [fileName]: {\n content: source,\n },\n },\n settings: {\n outputSelection: {\n '*': {\n '*': ['abi', 'evm.bytecode'],\n },\n },\n },\n };\n \n console.log(`Compiling contract: ${fileName}...`);\n \n // Compile the contract\n const output = JSON.parse(solc.compile(JSON.stringify(input)));\n \n // Check for errors\n if (output.errors) {\n const errors = output.errors.filter((error: any) => error.severity === 'error');\n if (errors.length > 0) {\n console.error('Compilation errors:');\n errors.forEach((err: any) => console.error(err.formattedMessage));\n return;\n }\n // Show warnings\n const warnings = output.errors.filter((error: any) => error.severity === 'warning');\n warnings.forEach((warn: any) => console.warn(warn.formattedMessage));\n }\n \n // Ensure output directories exist\n ensureDir(abiDir);\n ensureDir(artifactsDir);\n \n // Process compiled contracts\n for (const [sourceFile, contracts] of Object.entries(output.contracts)) {\n for (const [contractName, contract] of Object.entries(contracts as any)) {\n console.log(`Compiled contract: ${contractName}`);\n \n // Write the ABI\n const abiPath = join(abiDir, `${contractName}.json`);\n writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n \n // Write the bytecode\n const bytecodePath = join(artifactsDir, `${contractName}.bin`);\n writeFileSync(bytecodePath, (contract as any).evm.bytecode.object);\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath: string = './contracts/Storage.sol';\nconst abiDir: string = './abis';\nconst artifactsDir: string = './artifacts';\n\ncompileContract(solidityFilePath, abiDir, artifactsDir);\n```\n\nTo compile your contract:\n\n```bash\nnpm run compile\n```\n\nAfter executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 11, "depth": 2, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 10801, "end_char": 13426, "estimated_token_count": 610, "token_estimator": "heuristic-v1", "text": "## Deploy the Contract\n\nCreate a new file at `src/deploy.ts` for handling contract deployment:\n\n```typescript title=\"src/deploy.ts\"\nimport { existsSync, readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { createWallet } from './createWallet.ts';\nimport { publicClient } from './createClient.ts';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst ABIS_DIR = join(__dirname, '../abis');\nconst ARTIFACTS_DIR = join(__dirname, '../artifacts');\n\nconst deployContract = async (\n contractName: string,\n privateKey: `0x${string}`\n) => {\n try {\n console.log(`Deploying ${contractName}...`);\n\n const abiPath = join(ABIS_DIR, `${contractName}.json`);\n const bytecodePath = join(ARTIFACTS_DIR, `${contractName}.bin`);\n\n if (!existsSync(abiPath) || !existsSync(bytecodePath)) {\n throw new Error(\n `Missing artifacts for ${contractName}. Try running \"npm run compile\" first.`\n );\n }\n\n // Read contract artifacts\n const abi = JSON.parse(\n readFileSync(abiPath, 'utf8')\n );\n const bytecode = `0x${readFileSync(bytecodePath, 'utf8').trim()}` as `0x${string}`;\n\n // Create wallet\n const wallet = createWallet(privateKey);\n\n // Deploy contract\n const hash = await wallet.deployContract({\n abi,\n bytecode,\n args: [], // Add constructor arguments if needed\n });\n\n // Wait for deployment\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n const contractAddress = receipt.contractAddress;\n\n console.log(`Contract deployed at: ${contractAddress}`);\n return contractAddress;\n } catch (error) {\n console.error('Deployment failed:', error);\n throw error;\n }\n};\n\nconst privateKey = 'INSERT_PRIVATE_KEY';\ndeployContract('Storage', privateKey);\n```\n\nEnsure to replace `INSERT_PRIVATE_KEY` with the proper value. For further details on private key exportation, refer to the article [How to export an account's private key](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/){target=\\_blank}.\n\n!!! warning\n Never commit or share your private key. Exposed keys can lead to immediate theft of all associated funds. Use environment variables instead.\n\nTo deploy, run the following command:\n\n```bash\nnpm run deploy\n```\n\nIf everything is successful, you will see the address of your deployed contract displayed in the terminal. This address is unique to your contract on the network you defined in the chain configuration, and you'll need it for any future interactions with your contract."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 12, "depth": 2, "title": "Interact with the Contract", "anchor": "interact-with-the-contract", "start_char": 13426, "end_char": 15799, "estimated_token_count": 510, "token_estimator": "heuristic-v1", "text": "## Interact with the Contract\n\nCreate a new file at `src/interact.ts` for interacting with your deployed contract:\n\n```typescript title=\"src/interact.ts\"\nimport { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { publicClient } from './createClient.ts';\nimport { createWallet } from './createWallet.ts';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst ABI_PATH = join(__dirname, '../abis/Storage.json');\n\nconst STORAGE_ABI = JSON.parse(readFileSync(ABI_PATH, 'utf8'));\n\nconst interactWithStorage = async (\n contractAddress: `0x${string}`,\n privateKey: `0x${string}`\n) => {\n try {\n const wallet = createWallet(privateKey);\n const currentNumber = await publicClient.readContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'storedNumber',\n args: [],\n });\n console.log(`Stored number: ${currentNumber}`);\n\n const newNumber = BigInt(42);\n const { request } = await publicClient.simulateContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'setNumber',\n args: [newNumber],\n account: wallet.account,\n });\n\n const hash = await wallet.writeContract(request);\n await publicClient.waitForTransactionReceipt({ hash });\n console.log(`Number updated to ${newNumber}`);\n\n const updatedNumber = await publicClient.readContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'storedNumber',\n args: [],\n });\n console.log('Updated stored number:', updatedNumber);\n } catch (error) {\n console.error('Interaction failed:', error);\n }\n};\n\nconst PRIVATE_KEY = 'INSERT_PRIVATE_KEY';\nconst CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS';\n\ninteractWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY);\n```\n\nEnsure to replace `INSERT_PRIVATE_KEY` and `INSERT_CONTRACT_ADDRESS` with the proper values.\n\nTo interact with the contract:\n\n```bash\nnpm run interact\n```\n\nFollowing a successful interaction, you will see the stored value before and after the transaction. The output will show the initial stored number (0 if you haven't modified it yet), confirm when the transaction to set the number to 42 is complete, and then display the updated stored number value. This demonstrates both reading from and writing to your smart contract."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 13, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 15799, "end_char": 17568, "estimated_token_count": 545, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you have the foundation for using viem with Polkadot Hub, consider exploring:\n\n
\n\n- External __Advanced viem Features__\n\n ---\n Explore viem's documentation:\n
    \n
  • [:octicons-arrow-right-24: Multi call](https://viem.sh/docs/contract/multicall#multicall){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Batch transactions](https://viem.sh/docs/clients/transports/http#batch-json-rpc){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Custom actions](https://viem.sh/docs/clients/custom#extending-with-actions-or-configuration){target=\\_blank}
  • \n
\n\n- External __Test Frameworks__\n\n ---\n\n Integrate viem with the following frameworks for comprehensive testing:\n
    \n
  • [:octicons-arrow-right-24: Hardhat](https://hardhat.org/){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Foundry](https://getfoundry.sh/){target=\\_blank}
  • \n
\n\n- External __Event Handling__\n\n ---\n\n Learn how to subscribe to and process contract events:\n
    \n
  • [:octicons-arrow-right-24: Event subscription](https://viem.sh/docs/actions/public/watchEvent#watchevent){target=\\_blank}
  • \n
\n\n- External __Building dApps__\n\n ---\n\n Combine viem the following technologies to create full-stack applications:\n
    \n
  • [:octicons-arrow-right-24: Next.js](https://nextjs.org/docs){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Node.js](https://nodejs.org/en){target=\\_blank}
  • \n
\n\n
"} {"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 179, "end_char": 607, "estimated_token_count": 97, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[Wagmi](https://wagmi.sh/){target=\\_blank} is a collection of [React Hooks](https://wagmi.sh/react/api/hooks){target=\\_blank} for interacting with Ethereum-compatible blockchains, focusing on developer experience, feature richness, and reliability.\n\nThis guide demonstrates how to use Wagmi to interact with and deploy smart contracts to Polkadot Hub, providing a seamless frontend integration for your dApps."} {"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 1, "depth": 2, "title": "Set Up the Project", "anchor": "set-up-the-project", "start_char": 607, "end_char": 875, "estimated_token_count": 65, "token_estimator": "heuristic-v1", "text": "## Set Up the Project\n\nTo start working with Wagmi, create a new React project and initialize it by running the following commands in your terminal:\n\n```bash\n# Create a new React project using Next.js\nnpx create-next-app@latest wagmi-asset-hub\ncd wagmi-asset-hub\n```"} {"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 2, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 875, "end_char": 1037, "estimated_token_count": 34, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall Wagmi and its peer dependencies:\n\n```bash\n# Install Wagmi and its dependencies\nnpm install wagmi viem @tanstack/react-query\n```"} From c587d6132c01e0198cfb0bd1506b7c8c40c24b3e Mon Sep 17 00:00:00 2001 From: nhussein11 Date: Tue, 18 Nov 2025 12:21:52 -0300 Subject: [PATCH 3/3] fix: typo + llms --- .ai/categories/smart-contracts.md | 2 +- .ai/categories/tooling.md | 2 +- .ai/pages/smart-contracts-libraries-viem.md | 2 +- .ai/site-index.json | 8 ++++---- llms-full.jsonl | 22 ++++++++++----------- smart-contracts/libraries/viem.md | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.ai/categories/smart-contracts.md b/.ai/categories/smart-contracts.md index 80c6ce257..5443d4376 100644 --- a/.ai/categories/smart-contracts.md +++ b/.ai/categories/smart-contracts.md @@ -9672,7 +9672,7 @@ viem-project/ └── Storage.bin ``` -## Set Up the Proje +## Set Up the Project First, create a new folder and initialize your project: ```bash diff --git a/.ai/categories/tooling.md b/.ai/categories/tooling.md index 609e2c9fc..6c230c25d 100644 --- a/.ai/categories/tooling.md +++ b/.ai/categories/tooling.md @@ -11679,7 +11679,7 @@ viem-project/ └── Storage.bin ``` -## Set Up the Proje +## Set Up the Project First, create a new folder and initialize your project: ```bash diff --git a/.ai/pages/smart-contracts-libraries-viem.md b/.ai/pages/smart-contracts-libraries-viem.md index 5725beed9..9baa09b67 100644 --- a/.ai/pages/smart-contracts-libraries-viem.md +++ b/.ai/pages/smart-contracts-libraries-viem.md @@ -42,7 +42,7 @@ viem-project/ └── Storage.bin ``` -## Set Up the Proje +## Set Up the Project First, create a new folder and initialize your project: ```bash diff --git a/.ai/site-index.json b/.ai/site-index.json index 18be5c994..1d2a083e7 100644 --- a/.ai/site-index.json +++ b/.ai/site-index.json @@ -8583,8 +8583,8 @@ }, { "depth": 2, - "title": "Set Up the Proje", - "anchor": "set-up-the-proje" + "title": "Set Up the Project", + "anchor": "set-up-the-project" }, { "depth": 2, @@ -8638,12 +8638,12 @@ } ], "stats": { - "chars": 17568, + "chars": 17570, "words": 2024, "headings": 14, "estimated_token_count_total": 4177 }, - "hash": "sha256:f671e04fcab3c9af17f4dff8ffd4c6952c42b8e7397c30a1e0e11761e771cc31", + "hash": "sha256:0ec2590ef8889af04ae83bf38841986b9d56934488ee8314f0d45e1cf1d6e1c7", "token_estimator": "heuristic-v1" }, { diff --git a/llms-full.jsonl b/llms-full.jsonl index 717c50ccb..0b3383df6 100644 --- a/llms-full.jsonl +++ b/llms-full.jsonl @@ -1125,17 +1125,17 @@ {"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 8, "end_char": 285, "estimated_token_count": 56, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[viem](https://viem.sh/){target=\\_blank} is a lightweight TypeScript library designed for interacting with Ethereum-compatible blockchains. This comprehensive guide will walk you through using viem to interact with and deploy smart contracts to Polkadot Hub."} {"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 285, "end_char": 641, "estimated_token_count": 110, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore getting started, ensure you have the following installed:\n\n- **Node.js**: v22.13.1 or later, check the [Node.js installation guide](https://nodejs.org/en/download/current/){target=\\_blank}.\n- **npm**: v6.13.4 or later (comes bundled with Node.js).\n- **Solidity**: This guide uses Solidity `^0.8.9` for smart contract development."} {"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 2, "depth": 2, "title": "Project Structure", "anchor": "project-structure", "start_char": 641, "end_char": 1067, "estimated_token_count": 125, "token_estimator": "heuristic-v1", "text": "## Project Structure\n\nThis project organizes contracts, scripts, and compiled artifacts for easy development and deployment.\n\n```text\nviem-project/\n├── package.json\n├── tsconfig.json\n├── src/\n│ ├── chainConfig.ts\n│ ├── createClient.ts\n│ ├── createWallet.ts\n│ ├── compile.ts\n│ ├── deploy.ts\n│ └── interact.ts\n├── contracts/\n│ └── Storage.sol\n├── abis/\n│ └── Storage.json\n└── artifacts/\n └── Storage.bin\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 3, "depth": 2, "title": "Set Up the Proje", "anchor": "set-up-the-proje", "start_char": 1067, "end_char": 1204, "estimated_token_count": 36, "token_estimator": "heuristic-v1", "text": "## Set Up the Proje\nFirst, create a new folder and initialize your project:\n\n```bash\nmkdir viem-project\ncd viem-project\nnpm init -y\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 4, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 1204, "end_char": 1577, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall viem along with other necessary dependencies, including [`solc`](https://www.npmjs.com/package/solc){target=\\_blank}, which enables to compile smart contracts EVM bytecode:\n\n```bash\n# Install viem and resolc\nnpm install viem solc\n\n# Install TypeScript and development dependencies\nnpm install --save-dev typescript ts-node @types/node\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 5, "depth": 2, "title": "Initialize Project", "anchor": "initialize-project", "start_char": 1577, "end_char": 2087, "estimated_token_count": 137, "token_estimator": "heuristic-v1", "text": "## Initialize Project\n\nInitialize a TypeScript project by running the following command:\n\n```bash\nnpx tsc --init\n```\n\nAdd the following scripts to your `package.json` file to enable running TypeScript files:\n\n```json\n{\n \"scripts\": {\n \"client\": \"ts-node src/createClient.ts\",\n \"compile\": \"ts-node src/compile.ts\",\n \"deploy\": \"ts-node src/deploy.ts\",\n \"interact\": \"ts-node src/interact.ts\"\n },\n}\n```\n\nCreate a directory for your TypeScript source files:\n\n```bash\nmkdir src\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 6, "depth": 2, "title": "Set Up the Chain Configuration", "anchor": "set-up-the-chain-configuration", "start_char": 2087, "end_char": 3042, "estimated_token_count": 205, "token_estimator": "heuristic-v1", "text": "## Set Up the Chain Configuration\n\nThe first step is to set up the chain configuration. Create a new file at `src/chainConfig.ts`:\n\n```typescript title=\"src/chainConfig.ts\"\nimport { http } from 'viem';\n\nexport const TRANSPORT = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nexport const POLKADOT_HUB = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n```\n\nEnsure to replace `INSERT_RPC_URL`, `INSERT_CHAIN_ID`, `INSERT_CHAIN_NAME`, `INSERT_NETWORK_NAME`, `INSERT_CHAIN_DECIMALS`, `INSERT_CURRENCY_NAME`, and `INSERT_CURRENCY_SYMBOL` with the proper values. Check the [Connect to Polkadot](/smart-contracts/connect/){target=\\_blank} page for more information on the possible values."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 7, "depth": 2, "title": "Set Up the viem Client", "anchor": "set-up-the-viem-client", "start_char": 3042, "end_char": 5250, "estimated_token_count": 505, "token_estimator": "heuristic-v1", "text": "## Set Up the viem Client\n\nTo interact with the chain, you need to create a client that is used solely for reading data. To accomplish this, create a new file at `src/createClient.ts`:\n\n```typescript title=\"src/createClient.ts\"\nimport { createPublicClient, createWalletClient, http } from 'viem';\n\nconst transport = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create a public client for reading data\nexport const publicClient = createPublicClient({\n chain: assetHub,\n transport,\n});\n\n```\n\nAfter setting up the [Public Client](https://viem.sh/docs/clients/public#public-client){target=\\_blank}, you can begin querying the blockchain. Here's an example of fetching the latest block number:\n\n??? code \"Fetch Last Block code\"\n\n ```js title=\"src/fetchLastBlock.ts\"\n import { createPublicClient, http } from 'viem';\n\n const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready\n\n // Configure the Polkadot Hub chain\n const polkadotHubTestnet = {\n id: 420420422,\n name: 'Polkadot Hub TestNet',\n network: 'polkadot-hub-testnet',\n nativeCurrency: {\n decimals: 18,\n name: 'PAS',\n symbol: 'PAS',\n },\n rpcUrls: {\n default: {\n http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready\n },\n },\n } as const;\n\n // Create a public client for reading data\n export const publicClient = createPublicClient({\n chain: polkadotHubTestnet,\n transport,\n });\n\n const main = async () => {\n try {\n const block = await publicClient.getBlock();\n console.log('Last block: ' + block.number.toString());\n } catch (error: unknown) {\n console.error('Error connecting to Polkadot Hub TestNet: ' + error);\n }\n };\n\n main();\n ```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 8, "depth": 2, "title": "Set Up a Wallet", "anchor": "set-up-a-wallet", "start_char": 5250, "end_char": 6607, "estimated_token_count": 299, "token_estimator": "heuristic-v1", "text": "## Set Up a Wallet\n\nIn case you need to sign transactions, you will need to instantiate a [Wallet Client](https://viem.sh/docs/clients/wallet#wallet-client){target=\\_blank} object within your project. To do so, create `src/createWallet.ts`:\n\n```typescript title=\"src/createWallet.ts\"\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { createWalletClient, http } from 'viem';\n\nconst transport = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n public: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create a wallet client for writing data\nexport const createWallet = (privateKey: `0x${string}`) => {\n const account = privateKeyToAccount(privateKey);\n return createWalletClient({\n account,\n chain: assetHub,\n transport,\n });\n};\n```\n\n!!!note\n The wallet you import with your private key must have sufficient funds to pay for transaction fees when deploying contracts or interacting with them. Make sure to fund your wallet with the appropriate native tokens for the network you're connecting to."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 9, "depth": 2, "title": "Sample Smart Contract", "anchor": "sample-smart-contract", "start_char": 6607, "end_char": 7588, "estimated_token_count": 204, "token_estimator": "heuristic-v1", "text": "## Sample Smart Contract\n\nThis example demonstrates compiling a `Storage.sol` Solidity contract for deployment to Polkadot Hub. The contract's functionality stores a number and permits users to update it with a new value.\n\n```bash\nmkdir contracts artifacts\n```\n\nYou can use the following contract to interact with the blockchain. Paste the following contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n//SPDX-License-Identifier: MIT\n\n// Solidity files have to start with this pragma.\n// It will be used by the Solidity compiler to validate its version.\npragma solidity ^0.8.9;\n\ncontract Storage {\n // Public state variable to store a number\n uint256 public storedNumber;\n\n /**\n * Updates the stored number.\n *\n * The `public` modifier allows anyone to call this function.\n *\n * @param _newNumber - The new value to store.\n */\n function setNumber(uint256 _newNumber) public {\n storedNumber = _newNumber;\n }\n}\n```"} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 10, "depth": 2, "title": "Compile the Contract", "anchor": "compile-the-contract", "start_char": 7588, "end_char": 10801, "estimated_token_count": 749, "token_estimator": "heuristic-v1", "text": "## Compile the Contract\n\nCreate a new file at `src/compile.ts` for handling contract compilation:\n\n```typescript title=\"src/compile.ts\"\nimport solc from 'solc';\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { basename, join } from 'path';\n\nconst ensureDir = (dirPath: string): void => {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n};\n\nconst compileContract = (\n solidityFilePath: string,\n abiDir: string,\n artifactsDir: string\n): void => {\n try {\n // Read the Solidity file\n const source: string = readFileSync(solidityFilePath, 'utf8');\n const fileName: string = basename(solidityFilePath);\n \n // Construct the input object for the Solidity compiler\n const input = {\n language: 'Solidity',\n sources: {\n [fileName]: {\n content: source,\n },\n },\n settings: {\n outputSelection: {\n '*': {\n '*': ['abi', 'evm.bytecode'],\n },\n },\n },\n };\n \n console.log(`Compiling contract: ${fileName}...`);\n \n // Compile the contract\n const output = JSON.parse(solc.compile(JSON.stringify(input)));\n \n // Check for errors\n if (output.errors) {\n const errors = output.errors.filter((error: any) => error.severity === 'error');\n if (errors.length > 0) {\n console.error('Compilation errors:');\n errors.forEach((err: any) => console.error(err.formattedMessage));\n return;\n }\n // Show warnings\n const warnings = output.errors.filter((error: any) => error.severity === 'warning');\n warnings.forEach((warn: any) => console.warn(warn.formattedMessage));\n }\n \n // Ensure output directories exist\n ensureDir(abiDir);\n ensureDir(artifactsDir);\n \n // Process compiled contracts\n for (const [sourceFile, contracts] of Object.entries(output.contracts)) {\n for (const [contractName, contract] of Object.entries(contracts as any)) {\n console.log(`Compiled contract: ${contractName}`);\n \n // Write the ABI\n const abiPath = join(abiDir, `${contractName}.json`);\n writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n \n // Write the bytecode\n const bytecodePath = join(artifactsDir, `${contractName}.bin`);\n writeFileSync(bytecodePath, (contract as any).evm.bytecode.object);\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath: string = './contracts/Storage.sol';\nconst abiDir: string = './abis';\nconst artifactsDir: string = './artifacts';\n\ncompileContract(solidityFilePath, abiDir, artifactsDir);\n```\n\nTo compile your contract:\n\n```bash\nnpm run compile\n```\n\nAfter executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 11, "depth": 2, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 10801, "end_char": 13426, "estimated_token_count": 610, "token_estimator": "heuristic-v1", "text": "## Deploy the Contract\n\nCreate a new file at `src/deploy.ts` for handling contract deployment:\n\n```typescript title=\"src/deploy.ts\"\nimport { existsSync, readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { createWallet } from './createWallet.ts';\nimport { publicClient } from './createClient.ts';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst ABIS_DIR = join(__dirname, '../abis');\nconst ARTIFACTS_DIR = join(__dirname, '../artifacts');\n\nconst deployContract = async (\n contractName: string,\n privateKey: `0x${string}`\n) => {\n try {\n console.log(`Deploying ${contractName}...`);\n\n const abiPath = join(ABIS_DIR, `${contractName}.json`);\n const bytecodePath = join(ARTIFACTS_DIR, `${contractName}.bin`);\n\n if (!existsSync(abiPath) || !existsSync(bytecodePath)) {\n throw new Error(\n `Missing artifacts for ${contractName}. Try running \"npm run compile\" first.`\n );\n }\n\n // Read contract artifacts\n const abi = JSON.parse(\n readFileSync(abiPath, 'utf8')\n );\n const bytecode = `0x${readFileSync(bytecodePath, 'utf8').trim()}` as `0x${string}`;\n\n // Create wallet\n const wallet = createWallet(privateKey);\n\n // Deploy contract\n const hash = await wallet.deployContract({\n abi,\n bytecode,\n args: [], // Add constructor arguments if needed\n });\n\n // Wait for deployment\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n const contractAddress = receipt.contractAddress;\n\n console.log(`Contract deployed at: ${contractAddress}`);\n return contractAddress;\n } catch (error) {\n console.error('Deployment failed:', error);\n throw error;\n }\n};\n\nconst privateKey = 'INSERT_PRIVATE_KEY';\ndeployContract('Storage', privateKey);\n```\n\nEnsure to replace `INSERT_PRIVATE_KEY` with the proper value. For further details on private key exportation, refer to the article [How to export an account's private key](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/){target=\\_blank}.\n\n!!! warning\n Never commit or share your private key. Exposed keys can lead to immediate theft of all associated funds. Use environment variables instead.\n\nTo deploy, run the following command:\n\n```bash\nnpm run deploy\n```\n\nIf everything is successful, you will see the address of your deployed contract displayed in the terminal. This address is unique to your contract on the network you defined in the chain configuration, and you'll need it for any future interactions with your contract."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 12, "depth": 2, "title": "Interact with the Contract", "anchor": "interact-with-the-contract", "start_char": 13426, "end_char": 15799, "estimated_token_count": 510, "token_estimator": "heuristic-v1", "text": "## Interact with the Contract\n\nCreate a new file at `src/interact.ts` for interacting with your deployed contract:\n\n```typescript title=\"src/interact.ts\"\nimport { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { publicClient } from './createClient.ts';\nimport { createWallet } from './createWallet.ts';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst ABI_PATH = join(__dirname, '../abis/Storage.json');\n\nconst STORAGE_ABI = JSON.parse(readFileSync(ABI_PATH, 'utf8'));\n\nconst interactWithStorage = async (\n contractAddress: `0x${string}`,\n privateKey: `0x${string}`\n) => {\n try {\n const wallet = createWallet(privateKey);\n const currentNumber = await publicClient.readContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'storedNumber',\n args: [],\n });\n console.log(`Stored number: ${currentNumber}`);\n\n const newNumber = BigInt(42);\n const { request } = await publicClient.simulateContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'setNumber',\n args: [newNumber],\n account: wallet.account,\n });\n\n const hash = await wallet.writeContract(request);\n await publicClient.waitForTransactionReceipt({ hash });\n console.log(`Number updated to ${newNumber}`);\n\n const updatedNumber = await publicClient.readContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'storedNumber',\n args: [],\n });\n console.log('Updated stored number:', updatedNumber);\n } catch (error) {\n console.error('Interaction failed:', error);\n }\n};\n\nconst PRIVATE_KEY = 'INSERT_PRIVATE_KEY';\nconst CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS';\n\ninteractWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY);\n```\n\nEnsure to replace `INSERT_PRIVATE_KEY` and `INSERT_CONTRACT_ADDRESS` with the proper values.\n\nTo interact with the contract:\n\n```bash\nnpm run interact\n```\n\nFollowing a successful interaction, you will see the stored value before and after the transaction. The output will show the initial stored number (0 if you haven't modified it yet), confirm when the transaction to set the number to 42 is complete, and then display the updated stored number value. This demonstrates both reading from and writing to your smart contract."} -{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 13, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 15799, "end_char": 17568, "estimated_token_count": 545, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you have the foundation for using viem with Polkadot Hub, consider exploring:\n\n
\n\n- External __Advanced viem Features__\n\n ---\n Explore viem's documentation:\n
    \n
  • [:octicons-arrow-right-24: Multi call](https://viem.sh/docs/contract/multicall#multicall){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Batch transactions](https://viem.sh/docs/clients/transports/http#batch-json-rpc){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Custom actions](https://viem.sh/docs/clients/custom#extending-with-actions-or-configuration){target=\\_blank}
  • \n
\n\n- External __Test Frameworks__\n\n ---\n\n Integrate viem with the following frameworks for comprehensive testing:\n
    \n
  • [:octicons-arrow-right-24: Hardhat](https://hardhat.org/){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Foundry](https://getfoundry.sh/){target=\\_blank}
  • \n
\n\n- External __Event Handling__\n\n ---\n\n Learn how to subscribe to and process contract events:\n
    \n
  • [:octicons-arrow-right-24: Event subscription](https://viem.sh/docs/actions/public/watchEvent#watchevent){target=\\_blank}
  • \n
\n\n- External __Building dApps__\n\n ---\n\n Combine viem the following technologies to create full-stack applications:\n
    \n
  • [:octicons-arrow-right-24: Next.js](https://nextjs.org/docs){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Node.js](https://nodejs.org/en){target=\\_blank}
  • \n
\n\n
"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 3, "depth": 2, "title": "Set Up the Project", "anchor": "set-up-the-project", "start_char": 1067, "end_char": 1206, "estimated_token_count": 36, "token_estimator": "heuristic-v1", "text": "## Set Up the Project\nFirst, create a new folder and initialize your project:\n\n```bash\nmkdir viem-project\ncd viem-project\nnpm init -y\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 4, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 1206, "end_char": 1579, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall viem along with other necessary dependencies, including [`solc`](https://www.npmjs.com/package/solc){target=\\_blank}, which enables to compile smart contracts EVM bytecode:\n\n```bash\n# Install viem and resolc\nnpm install viem solc\n\n# Install TypeScript and development dependencies\nnpm install --save-dev typescript ts-node @types/node\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 5, "depth": 2, "title": "Initialize Project", "anchor": "initialize-project", "start_char": 1579, "end_char": 2089, "estimated_token_count": 137, "token_estimator": "heuristic-v1", "text": "## Initialize Project\n\nInitialize a TypeScript project by running the following command:\n\n```bash\nnpx tsc --init\n```\n\nAdd the following scripts to your `package.json` file to enable running TypeScript files:\n\n```json\n{\n \"scripts\": {\n \"client\": \"ts-node src/createClient.ts\",\n \"compile\": \"ts-node src/compile.ts\",\n \"deploy\": \"ts-node src/deploy.ts\",\n \"interact\": \"ts-node src/interact.ts\"\n },\n}\n```\n\nCreate a directory for your TypeScript source files:\n\n```bash\nmkdir src\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 6, "depth": 2, "title": "Set Up the Chain Configuration", "anchor": "set-up-the-chain-configuration", "start_char": 2089, "end_char": 3044, "estimated_token_count": 205, "token_estimator": "heuristic-v1", "text": "## Set Up the Chain Configuration\n\nThe first step is to set up the chain configuration. Create a new file at `src/chainConfig.ts`:\n\n```typescript title=\"src/chainConfig.ts\"\nimport { http } from 'viem';\n\nexport const TRANSPORT = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nexport const POLKADOT_HUB = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n```\n\nEnsure to replace `INSERT_RPC_URL`, `INSERT_CHAIN_ID`, `INSERT_CHAIN_NAME`, `INSERT_NETWORK_NAME`, `INSERT_CHAIN_DECIMALS`, `INSERT_CURRENCY_NAME`, and `INSERT_CURRENCY_SYMBOL` with the proper values. Check the [Connect to Polkadot](/smart-contracts/connect/){target=\\_blank} page for more information on the possible values."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 7, "depth": 2, "title": "Set Up the viem Client", "anchor": "set-up-the-viem-client", "start_char": 3044, "end_char": 5252, "estimated_token_count": 505, "token_estimator": "heuristic-v1", "text": "## Set Up the viem Client\n\nTo interact with the chain, you need to create a client that is used solely for reading data. To accomplish this, create a new file at `src/createClient.ts`:\n\n```typescript title=\"src/createClient.ts\"\nimport { createPublicClient, createWalletClient, http } from 'viem';\n\nconst transport = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create a public client for reading data\nexport const publicClient = createPublicClient({\n chain: assetHub,\n transport,\n});\n\n```\n\nAfter setting up the [Public Client](https://viem.sh/docs/clients/public#public-client){target=\\_blank}, you can begin querying the blockchain. Here's an example of fetching the latest block number:\n\n??? code \"Fetch Last Block code\"\n\n ```js title=\"src/fetchLastBlock.ts\"\n import { createPublicClient, http } from 'viem';\n\n const transport = http('https://testnet-passet-hub-eth-rpc.polkadot.io'); // TODO: change to paseo asset hub once ready\n\n // Configure the Polkadot Hub chain\n const polkadotHubTestnet = {\n id: 420420422,\n name: 'Polkadot Hub TestNet',\n network: 'polkadot-hub-testnet',\n nativeCurrency: {\n decimals: 18,\n name: 'PAS',\n symbol: 'PAS',\n },\n rpcUrls: {\n default: {\n http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready\n },\n },\n } as const;\n\n // Create a public client for reading data\n export const publicClient = createPublicClient({\n chain: polkadotHubTestnet,\n transport,\n });\n\n const main = async () => {\n try {\n const block = await publicClient.getBlock();\n console.log('Last block: ' + block.number.toString());\n } catch (error: unknown) {\n console.error('Error connecting to Polkadot Hub TestNet: ' + error);\n }\n };\n\n main();\n ```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 8, "depth": 2, "title": "Set Up a Wallet", "anchor": "set-up-a-wallet", "start_char": 5252, "end_char": 6609, "estimated_token_count": 299, "token_estimator": "heuristic-v1", "text": "## Set Up a Wallet\n\nIn case you need to sign transactions, you will need to instantiate a [Wallet Client](https://viem.sh/docs/clients/wallet#wallet-client){target=\\_blank} object within your project. To do so, create `src/createWallet.ts`:\n\n```typescript title=\"src/createWallet.ts\"\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { createWalletClient, http } from 'viem';\n\nconst transport = http('INSERT_RPC_URL');\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n public: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create a wallet client for writing data\nexport const createWallet = (privateKey: `0x${string}`) => {\n const account = privateKeyToAccount(privateKey);\n return createWalletClient({\n account,\n chain: assetHub,\n transport,\n });\n};\n```\n\n!!!note\n The wallet you import with your private key must have sufficient funds to pay for transaction fees when deploying contracts or interacting with them. Make sure to fund your wallet with the appropriate native tokens for the network you're connecting to."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 9, "depth": 2, "title": "Sample Smart Contract", "anchor": "sample-smart-contract", "start_char": 6609, "end_char": 7590, "estimated_token_count": 204, "token_estimator": "heuristic-v1", "text": "## Sample Smart Contract\n\nThis example demonstrates compiling a `Storage.sol` Solidity contract for deployment to Polkadot Hub. The contract's functionality stores a number and permits users to update it with a new value.\n\n```bash\nmkdir contracts artifacts\n```\n\nYou can use the following contract to interact with the blockchain. Paste the following contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n//SPDX-License-Identifier: MIT\n\n// Solidity files have to start with this pragma.\n// It will be used by the Solidity compiler to validate its version.\npragma solidity ^0.8.9;\n\ncontract Storage {\n // Public state variable to store a number\n uint256 public storedNumber;\n\n /**\n * Updates the stored number.\n *\n * The `public` modifier allows anyone to call this function.\n *\n * @param _newNumber - The new value to store.\n */\n function setNumber(uint256 _newNumber) public {\n storedNumber = _newNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 10, "depth": 2, "title": "Compile the Contract", "anchor": "compile-the-contract", "start_char": 7590, "end_char": 10803, "estimated_token_count": 749, "token_estimator": "heuristic-v1", "text": "## Compile the Contract\n\nCreate a new file at `src/compile.ts` for handling contract compilation:\n\n```typescript title=\"src/compile.ts\"\nimport solc from 'solc';\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { basename, join } from 'path';\n\nconst ensureDir = (dirPath: string): void => {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n};\n\nconst compileContract = (\n solidityFilePath: string,\n abiDir: string,\n artifactsDir: string\n): void => {\n try {\n // Read the Solidity file\n const source: string = readFileSync(solidityFilePath, 'utf8');\n const fileName: string = basename(solidityFilePath);\n \n // Construct the input object for the Solidity compiler\n const input = {\n language: 'Solidity',\n sources: {\n [fileName]: {\n content: source,\n },\n },\n settings: {\n outputSelection: {\n '*': {\n '*': ['abi', 'evm.bytecode'],\n },\n },\n },\n };\n \n console.log(`Compiling contract: ${fileName}...`);\n \n // Compile the contract\n const output = JSON.parse(solc.compile(JSON.stringify(input)));\n \n // Check for errors\n if (output.errors) {\n const errors = output.errors.filter((error: any) => error.severity === 'error');\n if (errors.length > 0) {\n console.error('Compilation errors:');\n errors.forEach((err: any) => console.error(err.formattedMessage));\n return;\n }\n // Show warnings\n const warnings = output.errors.filter((error: any) => error.severity === 'warning');\n warnings.forEach((warn: any) => console.warn(warn.formattedMessage));\n }\n \n // Ensure output directories exist\n ensureDir(abiDir);\n ensureDir(artifactsDir);\n \n // Process compiled contracts\n for (const [sourceFile, contracts] of Object.entries(output.contracts)) {\n for (const [contractName, contract] of Object.entries(contracts as any)) {\n console.log(`Compiled contract: ${contractName}`);\n \n // Write the ABI\n const abiPath = join(abiDir, `${contractName}.json`);\n writeFileSync(abiPath, JSON.stringify((contract as any).abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n \n // Write the bytecode\n const bytecodePath = join(artifactsDir, `${contractName}.bin`);\n writeFileSync(bytecodePath, (contract as any).evm.bytecode.object);\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath: string = './contracts/Storage.sol';\nconst abiDir: string = './abis';\nconst artifactsDir: string = './artifacts';\n\ncompileContract(solidityFilePath, abiDir, artifactsDir);\n```\n\nTo compile your contract:\n\n```bash\nnpm run compile\n```\n\nAfter executing this script, you will see the compilation results including the generated `Storage.json` (containing the contract's ABI) and `Storage.vin` (containing the compiled bytecode) files in the `artifacts` folder. These files contain all the necessary information for deploying and interacting with your smart contract on Polkadot Hub."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 11, "depth": 2, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 10803, "end_char": 13428, "estimated_token_count": 610, "token_estimator": "heuristic-v1", "text": "## Deploy the Contract\n\nCreate a new file at `src/deploy.ts` for handling contract deployment:\n\n```typescript title=\"src/deploy.ts\"\nimport { existsSync, readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { createWallet } from './createWallet.ts';\nimport { publicClient } from './createClient.ts';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst ABIS_DIR = join(__dirname, '../abis');\nconst ARTIFACTS_DIR = join(__dirname, '../artifacts');\n\nconst deployContract = async (\n contractName: string,\n privateKey: `0x${string}`\n) => {\n try {\n console.log(`Deploying ${contractName}...`);\n\n const abiPath = join(ABIS_DIR, `${contractName}.json`);\n const bytecodePath = join(ARTIFACTS_DIR, `${contractName}.bin`);\n\n if (!existsSync(abiPath) || !existsSync(bytecodePath)) {\n throw new Error(\n `Missing artifacts for ${contractName}. Try running \"npm run compile\" first.`\n );\n }\n\n // Read contract artifacts\n const abi = JSON.parse(\n readFileSync(abiPath, 'utf8')\n );\n const bytecode = `0x${readFileSync(bytecodePath, 'utf8').trim()}` as `0x${string}`;\n\n // Create wallet\n const wallet = createWallet(privateKey);\n\n // Deploy contract\n const hash = await wallet.deployContract({\n abi,\n bytecode,\n args: [], // Add constructor arguments if needed\n });\n\n // Wait for deployment\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n const contractAddress = receipt.contractAddress;\n\n console.log(`Contract deployed at: ${contractAddress}`);\n return contractAddress;\n } catch (error) {\n console.error('Deployment failed:', error);\n throw error;\n }\n};\n\nconst privateKey = 'INSERT_PRIVATE_KEY';\ndeployContract('Storage', privateKey);\n```\n\nEnsure to replace `INSERT_PRIVATE_KEY` with the proper value. For further details on private key exportation, refer to the article [How to export an account's private key](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/){target=\\_blank}.\n\n!!! warning\n Never commit or share your private key. Exposed keys can lead to immediate theft of all associated funds. Use environment variables instead.\n\nTo deploy, run the following command:\n\n```bash\nnpm run deploy\n```\n\nIf everything is successful, you will see the address of your deployed contract displayed in the terminal. This address is unique to your contract on the network you defined in the chain configuration, and you'll need it for any future interactions with your contract."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 12, "depth": 2, "title": "Interact with the Contract", "anchor": "interact-with-the-contract", "start_char": 13428, "end_char": 15801, "estimated_token_count": 510, "token_estimator": "heuristic-v1", "text": "## Interact with the Contract\n\nCreate a new file at `src/interact.ts` for interacting with your deployed contract:\n\n```typescript title=\"src/interact.ts\"\nimport { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { publicClient } from './createClient.ts';\nimport { createWallet } from './createWallet.ts';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst ABI_PATH = join(__dirname, '../abis/Storage.json');\n\nconst STORAGE_ABI = JSON.parse(readFileSync(ABI_PATH, 'utf8'));\n\nconst interactWithStorage = async (\n contractAddress: `0x${string}`,\n privateKey: `0x${string}`\n) => {\n try {\n const wallet = createWallet(privateKey);\n const currentNumber = await publicClient.readContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'storedNumber',\n args: [],\n });\n console.log(`Stored number: ${currentNumber}`);\n\n const newNumber = BigInt(42);\n const { request } = await publicClient.simulateContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'setNumber',\n args: [newNumber],\n account: wallet.account,\n });\n\n const hash = await wallet.writeContract(request);\n await publicClient.waitForTransactionReceipt({ hash });\n console.log(`Number updated to ${newNumber}`);\n\n const updatedNumber = await publicClient.readContract({\n address: contractAddress,\n abi: STORAGE_ABI,\n functionName: 'storedNumber',\n args: [],\n });\n console.log('Updated stored number:', updatedNumber);\n } catch (error) {\n console.error('Interaction failed:', error);\n }\n};\n\nconst PRIVATE_KEY = 'INSERT_PRIVATE_KEY';\nconst CONTRACT_ADDRESS = 'INSERT_CONTRACT_ADDRESS';\n\ninteractWithStorage(CONTRACT_ADDRESS, PRIVATE_KEY);\n```\n\nEnsure to replace `INSERT_PRIVATE_KEY` and `INSERT_CONTRACT_ADDRESS` with the proper values.\n\nTo interact with the contract:\n\n```bash\nnpm run interact\n```\n\nFollowing a successful interaction, you will see the stored value before and after the transaction. The output will show the initial stored number (0 if you haven't modified it yet), confirm when the transaction to set the number to 42 is complete, and then display the updated stored number value. This demonstrates both reading from and writing to your smart contract."} +{"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 13, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 15801, "end_char": 17570, "estimated_token_count": 545, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you have the foundation for using viem with Polkadot Hub, consider exploring:\n\n
\n\n- External __Advanced viem Features__\n\n ---\n Explore viem's documentation:\n
    \n
  • [:octicons-arrow-right-24: Multi call](https://viem.sh/docs/contract/multicall#multicall){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Batch transactions](https://viem.sh/docs/clients/transports/http#batch-json-rpc){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Custom actions](https://viem.sh/docs/clients/custom#extending-with-actions-or-configuration){target=\\_blank}
  • \n
\n\n- External __Test Frameworks__\n\n ---\n\n Integrate viem with the following frameworks for comprehensive testing:\n
    \n
  • [:octicons-arrow-right-24: Hardhat](https://hardhat.org/){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Foundry](https://getfoundry.sh/){target=\\_blank}
  • \n
\n\n- External __Event Handling__\n\n ---\n\n Learn how to subscribe to and process contract events:\n
    \n
  • [:octicons-arrow-right-24: Event subscription](https://viem.sh/docs/actions/public/watchEvent#watchevent){target=\\_blank}
  • \n
\n\n- External __Building dApps__\n\n ---\n\n Combine viem the following technologies to create full-stack applications:\n
    \n
  • [:octicons-arrow-right-24: Next.js](https://nextjs.org/docs){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Node.js](https://nodejs.org/en){target=\\_blank}
  • \n
\n\n
"} {"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 179, "end_char": 607, "estimated_token_count": 97, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[Wagmi](https://wagmi.sh/){target=\\_blank} is a collection of [React Hooks](https://wagmi.sh/react/api/hooks){target=\\_blank} for interacting with Ethereum-compatible blockchains, focusing on developer experience, feature richness, and reliability.\n\nThis guide demonstrates how to use Wagmi to interact with and deploy smart contracts to Polkadot Hub, providing a seamless frontend integration for your dApps."} {"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 1, "depth": 2, "title": "Set Up the Project", "anchor": "set-up-the-project", "start_char": 607, "end_char": 875, "estimated_token_count": 65, "token_estimator": "heuristic-v1", "text": "## Set Up the Project\n\nTo start working with Wagmi, create a new React project and initialize it by running the following commands in your terminal:\n\n```bash\n# Create a new React project using Next.js\nnpx create-next-app@latest wagmi-asset-hub\ncd wagmi-asset-hub\n```"} {"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 2, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 875, "end_char": 1037, "estimated_token_count": 34, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall Wagmi and its peer dependencies:\n\n```bash\n# Install Wagmi and its dependencies\nnpm install wagmi viem @tanstack/react-query\n```"} diff --git a/smart-contracts/libraries/viem.md b/smart-contracts/libraries/viem.md index 351c1656d..cc29afe6a 100644 --- a/smart-contracts/libraries/viem.md +++ b/smart-contracts/libraries/viem.md @@ -41,7 +41,7 @@ viem-project/ └── Storage.bin ``` -## Set Up the Proje +## Set Up the Project First, create a new folder and initialize your project: ```bash