Skip to content

Commit 3ebb4a6

Browse files
docs: adjust viem docs using stcelo as feedback
1 parent a8898e5 commit 3ebb4a6

File tree

2 files changed

+104
-26
lines changed

2 files changed

+104
-26
lines changed

packages/sdk/contractkit/MIGRATION-TO-ETHERS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ provider.getTransaction(...)
6060

6161
I'll show the most "basic" interaction, which is a transfer. On CELO, it comes with a twist, you can transfer 4 currencies, CELO, cUSD, cEUR, and cREAL.
6262

63-
You can get the addresses on these tokens by heading to the explorer and getting their abi and addresses, or you can also use our [registry contract](https://docs.celo.org/developer/contractkit/contracts-wrappers-registry).
63+
You can get the addresses on these tokens by heading to the explorer and getting their abi and addresses, or you can also use our [registry contract](https://docs.celo.org/developer/contractkit/contracts-wrappers-registry). You can also use the [`@celo/abis`](https://www.npmjs.com/package/@celo/abis) package to get the ABIs directly.
6464

6565
```ts
6666
// this address is constant

packages/sdk/contractkit/MIGRATION-TO-VIEM.md

+103-25
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Hello devs 🌱 this is a migration path away from contractkit following the [pu
1313
+ import { createPublicClient, http } from 'viem'
1414
+ import { celo, celoAlfajores } from 'viem/chains'
1515
+
16-
+ const client = createPublicClient({
16+
+ const publicClient = createPublicClient({
1717
+ chain: celoAlfajores, // or celo for celo's mainnet
1818
+ transport: http()
1919
+ })
@@ -29,24 +29,29 @@ With viem:
2929

3030
```diff
3131
- const accounts = await kit.web3.eth.getAccounts();
32-
+ const accounts = await client.getAddresses()
32+
+ const accounts = await publicClient.getAddresses()
3333
const defaultAccount = accounts[0];
3434
```
3535

3636
### Get wallet
3737

3838
With viem:
3939

40-
> [viem does not currently support](<[source](https://viem.sh/docs/ethers-migration.html#viem-11)>) client-side signing (it's coming shortly!) – until then, you can use an Ethers Wallet
40+
> [viem does not full support](<[source](https://viem.sh/docs/ethers-migration.html#viem-11)>) client-side signing (it's coming shortly!) – until then, you can use an Ethers Wallet, however it does support `signMessage` and `signTypedData` already.
4141
4242
```diff
43+
+ import { privateKeyToAccount } from 'viem/accounts'
44+
+
45+
+ const privateKey = "0x...";
4346
+ const walletClient = createWalletClient({
4447
+ transport: http(celoAlfajores.rpcUrls.default.http[0] as string),
4548
+ chain: celoAlfajores,
4649
+ });
47-
+ const provider = new JsonRpcProvider(celoAlfajores.rpcUrls.default.http[0]);
48-
+ const wallet = new Wallet(privateKey, provider);
49-
+ const account = getAccount(wallet);
50+
+ const account = privateKeyToAccount(privateKey);
51+
+ await walletClient.signMessage({
52+
+ account,
53+
+ message: 'hello world',
54+
+ })
5055
```
5156

5257
### Provider methods
@@ -55,40 +60,60 @@ With viem:
5560
- const provider = kit.connection.web3.currentProvider
5661
- kit.connection.getBlock(...)
5762
- kit.connection.getTransaction(...)
58-
+ client.getBlock(...)
59-
+ client.getTransaction(...)
63+
+ const block = await publicClient.getBlock()
64+
+ /**
65+
+ * {
66+
+ * baseFeePerGas: 10000n,
67+
+ * number: 1234n,
68+
+ * parentHash: "0x....",
69+
+ * ...
70+
+ * }
71+
+ */
72+
+ const tx = await publicClient.getTransaction({
73+
+ hash: "0x...",
74+
+ })
75+
+ /**
76+
+ * {
77+
+ * blockHash: '0x...',
78+
+ * blockNumber: 1234n,
79+
+ * from: '0x...',
80+
+ * ...
81+
+ * }
82+
+ */
6083
```
6184

6285
### Signer methods
6386

6487
```diff
6588
- const provider = kit.connection.web3.currentProvider
6689
- const signer = provider.getSigner(kit.connection.defaultAccount)
67-
+ const [address] = await client.getAddresses()
68-
+ const account = getAccount(address)
69-
+ client.sendTransaction({ account, ... })
90+
+ const [account] = await walletClient.getAddresses()
91+
+ const hash = await walletClient.sendTransaction({ account, to: "0x...", value: 1000n })
7092
```
7193

7294
### Contract interaction
7395

7496
I'll show the most "basic" interaction, which is a transfer. On CELO, it comes with a twist, you can transfer 4 currencies, CELO, cUSD, cEUR, and cREAL.
7597

76-
You can get the addresses on these tokens by heading to the explorer and getting their abi and addresses, or you can also use our [registry contract](https://docs.celo.org/developer/contractkit/contracts-wrappers-registry).
98+
You can get the addresses on these tokens by heading to the explorer and getting their abi and addresses, or you can also use our [registry contract](https://docs.celo.org/developer/contractkit/contracts-wrappers-registry). You can also use the [`@celo/abis`](https://www.npmjs.com/package/@celo/abis) package to get the ABIs directly.
7799

78100
```ts
101+
import { getContract } from 'viem'
102+
import { registryABI } from '@celo/abis/types/viem'
103+
79104
// this address is constant
80105
const REGISTRY_CONTRACT_ADDRESS = '0x000000000000000000000000000000000000ce10'
81-
const registry = new Contract(REGISTRY_CONTRACT_ADDRESS, registryAbi, wallet)
106+
const registryContract = getContract({
107+
address: REGISTRY_CONTRACT_ADDRESS,
108+
abi: registryABI,
109+
publicClient,
110+
})
82111

83-
async function getToken(token: string) {
84-
const tokenAddress = await registry.getAddressForString(token)
85-
return tokenAddress
86-
}
87112
async function CeloTokens(): Promise<[string, string][]> {
88113
return Promise.all(
89114
['GoldToken', 'StableToken', 'StableTokenEUR', 'StableTokenBRL'].map(async (token) => [
90115
token,
91-
await getToken(token),
116+
await registryContract.read.getAddressForString(token),
92117
])
93118
)
94119
}
@@ -97,14 +122,15 @@ async function CeloTokens(): Promise<[string, string][]> {
97122
#### Balance
98123

99124
```diff
100-
+ import { tokenAbi } from './abi.json'
125+
+ import { stableTokenABI } from '@celo/abis/types/viem'
101126

102127
- const contract = await kit.contracts.getGoldToken();
103128
- const balance = await contract.balanceOf(wallet.address);
104-
+ const tokenAddress = '0x...' // Grabbed from the registry or from the explorer
129+
+ const tokenAddresses = await CeloTokens();
130+
+ const cUSD = tokenAddresses["StableToken]
105131
+ const balance = await client.readContract({
106132
+ abi: tokenAbi,
107-
+ address: tokenAddress,
133+
+ address: cUSD,
108134
+ functionName: "balanceOf",
109135
+ args: [account.address],
110136
+ });
@@ -115,11 +141,63 @@ async function CeloTokens(): Promise<[string, string][]> {
115141
Then, use the address of the token that you need and call the transfer method of the contract.
116142

117143
```diff
118-
+ import { tokenAbi } from './abi.json'
144+
+ import { stableTokenABI } from '@celo/abis/types/viem'
119145
- const CELO = await kit.contracts.getGoldToken();
120146
- const txReceipt = await CELO.transfer('0x...', amount)
121-
+ const tokenAddress = '0x...'
122-
+ const transfer = await walletClient.simulateContract({abi, address: tokenAddress, functionName: 'transfer', args: ['0x...', amount] })
147+
+ const tokenAddresses = await CeloTokens();
148+
+ const cUSD = tokenAddresses["StableToken]
149+
+ const { request } = await walletClient.simulateContract({
150+
+ abi,
151+
+ address: cUSD,
152+
+ functionName: 'transfer',
153+
+ args: [
154+
+ '0x...', // to address
155+
+ amount: 1000n,
156+
+ ],
157+
+ account: '0x...', // from address
158+
+ })
159+
+ const hash = await walletClient.sendTransaction(request);
123160
```
124161

125-
For more in depth examples, I highly recommend checking out the extensive documentations of both [ethers](https://docs.ethers.org/) and [viem](https://viem.sh/).
162+
#### Multicall
163+
164+
While contractkit didn't directly support multicall, you could use libraries such as `@dopex-io/web3-multicall` as such:
165+
166+
```ts
167+
import Multicall from '@dopex-io/web3-multicall'
168+
const MULTICALL_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11' // same on mainnet and alfajores
169+
const multicall = new Multicall({
170+
provider,
171+
chainId,
172+
multicallAddress: MULTICALL_ADDRESS,
173+
})
174+
const governance = await kit.contracts._web3Contracts.getGovernance()
175+
const stageTxs = _dequeue.map((proposalId) => governance.methods.getProposalStage(proposalId))
176+
const stages: string[] = await multicall.aggregate(stageTxs)
177+
```
178+
179+
You now can use `viem` directly to multicall since they have the address configured in the `viem/chains` files.
180+
181+
```ts
182+
const governanceAddress = await registryContract.read.getAddressForString(['Governance'])
183+
const governanceContract = getContract({
184+
address: governanceAddress,
185+
abi: governanceABI,
186+
publicClient,
187+
})
188+
const _dequeue = await governanceContract.read.getDequeue()
189+
const stageCalls = _dequeue.map((proposalId) => ({
190+
address: governanceAddress,
191+
abi: governanceABI,
192+
functionName: 'getProposalStage',
193+
args: [proposalId],
194+
}))
195+
const stages = (await publicClient.multicall({ contracts: stageCalls })).map((x) => x.result)
196+
```
197+
198+
### Further reading
199+
200+
For more in depth examples and documentation about viem specifically, I highly recommend checking out the extensive documentations of [viem](https://viem.sh/).
201+
202+
Another interesting application to help you migrate could be StCelo-v2.
203+
You can checkout the changes going from `react-celo` + `contractkit` to `rainbowkit` + `wagmi` + `viem` in [this pull-request](https://github.com/celo-org/staked-celo-web-app/pull/129).

0 commit comments

Comments
 (0)