diff --git a/.husky/pre-commit b/.husky/pre-commit index 84aec53..49190d4 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,2 +1,4 @@ +bun install +git add bun.lockb bun lint-staged diff --git a/bun.lockb b/bun.lockb index fced49a..4487f4c 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/content/10.js/01.web3js/00.index.md b/content/10.js/01.web3js/00.index.md index d6079b3..6453678 100644 --- a/content/10.js/01.web3js/00.index.md +++ b/content/10.js/01.web3js/00.index.md @@ -81,5 +81,8 @@ Insights into managing smart accounts on the ZKsync network. :: :: +Watch the [demo video](https://www.youtube.com/watch?v=RkNvE_FRr_A) on YouTube: +[![YouTube Demo](https://img.youtube.com/vi/RkNvE_FRr_A/maxresdefault.jpg)](https://www.youtube.com/watch?v=RkNvE_FRr_A) + The Web3.js plugin for ZKsync was made with 💛 by [ChainSafe](https://chainsafe.io/) ![ChainSafe](/images/chainsafe.png "ChainSafe") diff --git a/content/10.js/01.web3js/07.contracts.md b/content/10.js/01.web3js/07.contracts.md index 286c3f9..e36a8cc 100644 --- a/content/10.js/01.web3js/07.contracts.md +++ b/content/10.js/01.web3js/07.contracts.md @@ -48,24 +48,25 @@ async function main() { // replace with actual values const contractAbi: ContractAbi = []; - const constractByteCode: Bytes = ""; + const contractByteCode: Bytes = ""; // create a ContractFactory that uses the default create deployment type const contractFactory: ContractFactory = new ContractFactory( contractAbi, - constractByteCode, + contractByteCode, wallet, ); // or specify the deployment type // const contractFactory: ContractFactory = new ContractFactory( // contractAbi, - // constractByteCode, + // contractByteCode, // wallet, // "createAccount", // ); const contract: Contract = await contractFactory.deploy(); + console.log("Contract address:", contract.options.address); console.log("Contract methods:", contract.methods); } @@ -114,3 +115,107 @@ const returnValue = await contract.methods .contractMethod(/* method parameters, if any */) .call(); ``` + +## Interact with an existing smart contract + +The example above demonstrates interacting with a new smart contract that was deployed with a `ContractFactory`. The +following examples demonstrate instantiating and interacting with an existing smart contract. + +To instantiate an existing smart contract from a server-side environment (e.g. Node.js), use a `ZKsyncWallet` and its +`provider` property to construct a new `Contract` object as demonstrated in the following code sample: + +```ts +import { Contract, ContractAbi, Web3 } from "web3"; +import { + types, + Web3ZKsyncL2, + ZKsyncPlugin, + ZKsyncWallet, +} from "web3-plugin-zksync"; + +async function main() { + const web3: Web3 = new Web3(/* optional L1 provider */); + web3.registerPlugin( + new ZKsyncPlugin( + Web3ZKsyncL2.initWithDefaultProvider(types.Network.Sepolia), + ), + ); + const zksync: ZKsyncPlugin = web3.ZKsync; + + const PRIVATE_KEY: string = ""; + const wallet: ZKsyncWallet = new zksync.Wallet(PRIVATE_KEY); + + // replace with actual values + const contractAbi: ContractAbi = []; + const contractAddress: string = ""; + + // use the wallet and its provider to instantiate the contract + const contract: Contract = new wallet.provider!.eth.Contract( + contractAbi, + contractAddress, + ); + + const returnValue = await contract.methods + .contractMethod(/* method parameters, if any */) + .call(); +} + +main() + .then(() => console.log("✅ Script executed successfully")) + .catch((error) => console.error(`❌ Error executing script: ${error}`)); +``` + +The following React component demonstrates instantiating and interacting with an existing smart contract using an +injected provider (e.g. MetaMask): + +```ts +import { useEffect, useState } from "react"; + +import { Contract, ContractAbi } from "web3"; +import { ZKsyncPlugin } from "web3-plugin-zksync"; + +function App() { + const [zksync, setZKsync] = useState(null); + useEffect(() => { + if (window.ethereum) { + setZKsync(new ZKsyncPlugin(window.ethereum)); + } else { + console.error("No injected providers"); + } + }, []); + + useEffect(() => { + if (!zksync) { + return; + } + + // replace with actual values + const contractAbi: ContractAbi = []; + const contractAddress: string = ""; + + // use the plugin and its provider to instantiate the contract + const contract: Contract = new zksync.L2.eth.Contract( + contractAbi, + contractAddress, + ); + + const callContract = async () => { + // use an injected account to interact with the smart contract + const allAccounts = await zksync.L2.eth.requestAccounts(); + // send a transaction that updates the state of the smart contract + const transactionReceipt = await contract.methods + .contractMethod(/* method parameters, if any */) + .send({ from: allAccounts[0] }); + // call a smart contract to inspect its state + const returnValue = await contract.methods + .contractMethod(/* method parameters, if any */) + .call(); + }; + + callContract(); + }, [zksync]); + return
; +} + +export default App; +``` diff --git a/package.json b/package.json index 9016cbf..fa94ade 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "typescript": "^5.0.0" }, "dependencies": { - "@matterlabs/docs-nuxt-template": "2.8.5", + "@matterlabs/docs-nuxt-template": "2.9.1", "@iconify-json/heroicons": "^1.2.0", "@iconify-json/simple-icons": "^1.2.1", "@iconify-json/vscode-icons": "^1.2.0",