Skip to content
This repository was archived by the owner on Dec 11, 2024. It is now read-only.

Commit 8bc5bfb

Browse files
docs: add a migration guide (#363)
* docs: add a migration guide * notice about deprecation on readme * upgrade guide for v2 * add link and set date --------- Co-authored-by: Aaron DeRuvo <aaron.deruvo@clabs.co>
1 parent 004161b commit 8bc5bfb

File tree

2 files changed

+286
-7
lines changed

2 files changed

+286
-7
lines changed

migration-notes.md

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
# Draft: Migration document from react-celo to rainbowkit
2+
3+
Hello devs 🌱 this is a migration path away from react-celo, formerly known as use-contractkit. With the rise of ethers and viem, came really cool "Modal libraries" to help connect to dapps. This guide will cover [rainbowkit](https://www.rainbowkit.com/) and how to start using it instead of react-celo. This will mention a couple key differences between contractkit+web3, powering react-celo and viem, powering rainbowkit, but a more detailled guide can [be found here](https://github.com/celo-org/celo-monorepo/blob/8e2e2c5c53bd7f7c5df4f2a64974555ad0250615/packages/sdk/contractkit/MIGRATION-TO-VIEM.md)
4+
5+
## Requirements
6+
7+
```bash
8+
npm install @rainbow-me/rainbowkit@2 wagmi@2 viem@2.x @tanstack/react-query
9+
```
10+
11+
Optional recommended packages
12+
13+
```bash
14+
npm install @celo/abis
15+
```
16+
17+
## Initialization
18+
19+
```ts
20+
// react-celo
21+
import { CeloProvider } from '@celo/react-celo';
22+
import '@celo/react-celo/lib/styles.css';
23+
24+
function WrappedApp() {
25+
return (
26+
<CeloProvider
27+
dapp={{
28+
name: 'My awesome dApp',
29+
description: 'My awesome description',
30+
url: 'https://example.com',
31+
// if you plan on supporting WalletConnect compatible wallets, you need to provide a project ID, you can find it here: https://docs.walletconnect.com/2.0/cloud/relay
32+
walletConnectProjectId: '123',
33+
}}
34+
>
35+
<App />
36+
</CeloProvider>
37+
);
38+
}
39+
```
40+
41+
```ts
42+
// rainbowkit
43+
import '@rainbow-me/rainbowkit/styles.css'
44+
45+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
46+
import { WagmiProvider, http } from 'wagmi'
47+
import { celo, celoAlfajores } from 'wagmi/chains';
48+
import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
49+
import { getDefaultConfig } from '@rainbow-me/rainbowkit'
50+
51+
const config = getDefaultConfig({
52+
appName: 'Your app',
53+
projectId: 'YOUR_PROJECT_ID',
54+
chains: [celo, celoAlfajores],
55+
transports: {
56+
[celo.id]: http(),
57+
[celoAlfajores.id]: http(),
58+
},
59+
})
60+
61+
function WrappedApp() {
62+
return (
63+
<WagmiProvider config={config}>
64+
<QueryClientProvider client={queryClient}>
65+
<RainbowKitProvider>
66+
{/* Your App */}
67+
</RainbowKitProvider>
68+
</QueryClientProvider>
69+
</WagmiProvider>
70+
);
71+
}
72+
```
73+
74+
While this may seem like more boilerplate, and it is, however it's also a lot more flexible since it can handle others chains out of the box, contrary to react-celo.
75+
76+
For example:
77+
78+
```diff
79+
import { configureChains } from 'wagmi';
80+
- import { celo, celoAlfajores } from 'wagmi/chains';
81+
+ import { celo, celoAlfajores, avalanche, mainnet } from 'wagmi/chains';
82+
83+
const { chains, publicClient } = configureChains(
84+
- [celo, celoAlfajores],
85+
+ [celo, celoAlfajores, mainnet, avalanche],
86+
...
87+
);
88+
```
89+
90+
## Basic usage
91+
92+
Here we will cover the most basic interactions your dapp will have to implement to be able to interact with its users: connecting to a wallet, sending a transaction, displaying some chain data.
93+
94+
### Connecting your dapp to a wallet
95+
96+
```ts
97+
// react-celo
98+
import { useCelo } from '@celo/react-celo';
99+
100+
function App() {
101+
const { connect, address } = useCelo();
102+
103+
return (
104+
<>
105+
{address ? (
106+
<div>Connected to {address}</div>
107+
) : (
108+
<button onClick={connect}>Connect wallet</button>
109+
)}
110+
</>
111+
);
112+
}
113+
```
114+
115+
```ts
116+
// rainbowkit
117+
import { ConnectButton } from '@rainbow-me/rainbowkit';
118+
119+
function App() {
120+
const { connect, address } = useCelo();
121+
122+
return <ConnectButton />;
123+
}
124+
```
125+
126+
More details regarding the connect button `props` in the [rainbowkit docs](https://www.rainbowkit.com/docs/connect-button)
127+
128+
### Reading chain data
129+
130+
Firstly, you need to be aware that rainbowkit is a more general library than react-celo ever claimed to be. So it's natural some more specific Celo helpers/boilerplate will need to be implemented on your side. Thankfully, it should be very few, and probably even fewer as time goes.
131+
132+
```ts
133+
// ./use-celo-registry-address.ts
134+
// Helper to interact with the celo registry, abstracted in contractkit
135+
// We will probably add it to rainbowkit-celo, but until then, feel free
136+
// to copy the following snippet in your codebase
137+
import { useContractRead } from 'wagmi';
138+
import { registryABI } from '@celo/abis/types/wagmi';
139+
140+
export default function useCeloRegistryAddress(contractName: string) {
141+
const { data: address } = useContractRead({
142+
address: '0x000000000000000000000000000000000000ce10', // constant on mainnet and alfajores
143+
abi: registryABI,
144+
functionName: 'getAddressForString',
145+
args: [contractName],
146+
});
147+
148+
if (address && parseInt(address, 16) === 0) {
149+
return undefined;
150+
}
151+
return address;
152+
}
153+
```
154+
155+
You will see in the example below, the paradigm shifts from using imperative async functions to gather data to a more declarative "react-y" style, using hooks.
156+
157+
With rainbowkit using wagmi under the hood, the possiblities are pretty much endless, so here is a straightforward example trying to read data from a contract.
158+
159+
```diff
160+
- import { useCelo } from '@celo/react-celo';
161+
+ import { useAccount } from 'wagmi';
162+
+ import { accountsABI } from '@celo/abis/types/wagmi';
163+
+ import useCeloRegistryAddress from './use-celo-registry-address';
164+
165+
+ function useAccountSummary() {
166+
+ const { isConnected, address } = useAccount();
167+
+ const { data: accountSummary } = useContractRead({
168+
+ address: useCeloRegistryAddress('Accounts'),
169+
+ abi: accountsABI,
170+
+ functionName: 'getAccountSummary',
171+
+ });
172+
+
173+
+ return accountSummary
174+
+ }
175+
176+
function App() {
177+
- const { kit, address } = useCelo();
178+
-
179+
- async function getAccountSummary() {
180+
- const accounts = await kit.contracts.getAccounts();
181+
- await accounts.getAccountSummary(address);
182+
- }
183+
+ const accountSummary = useAccountSummary();
184+
185+
return (
186+
...
187+
)
188+
}
189+
```
190+
191+
### Send a transaction
192+
193+
```ts
194+
// react-celo
195+
import { useCelo } from '@celo/react-celo';
196+
197+
function App() {
198+
const { performActions } = useCelo();
199+
200+
async function transfer() {
201+
await performActions(async (kit) => {
202+
const cUSD = await kit.contracts.getStableToken();
203+
await cUSD.transfer('0x...', 10000).sendAndWaitForReceipt();
204+
});
205+
}
206+
207+
return <button onClick={transfer}>Transfer</button>;
208+
}
209+
```
210+
211+
Rainbowkit doesn't support a similar function as `performActions` out of the box, but you may achieve a similar result using `react-modal` and a simple `useState`.
212+
213+
```ts
214+
// rainbowkit
215+
import { usePrepareContractWrite, useContractWrite } from 'wagmi';
216+
import { StableTokenABI } from '@celo/abis/types/wagmi';
217+
import useCeloRegistryAddress from './use-celo-registry-address';
218+
// optional
219+
import MyCustomModal from './modal';
220+
221+
function App() {
222+
// optional modal state
223+
const [isOpen, setIsOpen] = useState(false);
224+
225+
const { config } = usePrepareContractWrite({
226+
address: useCeloRegistryAddress('StableToken'),
227+
abi: StableTokenABI,
228+
functionName: 'transfer',
229+
args: ['0x...', 10000],
230+
onSettle: () => setIsOpen(false),
231+
});
232+
const { write } = useContractWrite(config);
233+
const transfer = useCallback(() => {
234+
setIsOpen(true);
235+
write();
236+
}, [write]);
237+
238+
return;
239+
<>
240+
<button onClick={transfer}>Transfer</button>
241+
{isOpen && <MyCustomModal />}
242+
</>;
243+
}
244+
```
245+
246+
### Fee currency
247+
248+
While react-celo provides a `feeCurrency` variable and an `updateFeeCurrency` helper method, this isn't the case for rainbowkit. However, rainbowkit@2.0+ also supports `feeCurrency` out of the box thanks to its Celo-specific block and transactions formatters.
249+
250+
```tsx
251+
252+
import { useSendTransaction } from 'wagmi'
253+
254+
function App() {
255+
const { sendTransaction } = useSendTransaction()
256+
257+
return (
258+
<button
259+
onClick={() =>
260+
sendTransaction({
261+
to: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
262+
value: parseEther('0.01'),
263+
feeCurrency: '<USDC TOKEN ADDRESS HERE>'
264+
})
265+
}
266+
>
267+
Send transaction
268+
</button>
269+
)
270+
}
271+
272+
```
273+
274+
## Further reading
275+
276+
For more in depth examples and documentation about wagmi specifically, I highly recommend checking out the [extensive documentations of wagmi](https://wagmi.sh/react/getting-started). Rainbowkit also does a good job at documenting their library so make sure to [check it out](https://www.rainbowkit.com/docs/introduction)!
277+
278+
Another interesting application to help you migrate could be StCelo-v2. 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).

readme.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# react-celo
22

3-
(_Formerly known as use-contractkit. [read the upgrade guide](/guides/migrate-to-v4.md)_)
3+
> [!CAUTION]
4+
> React-Celo is now in [the end of of its life](https://forum.celo.org/t/celo-react-celo-deprecation-and-intent-sunset-notice/8082). Do not use for new projects and please migrate to an alternative by 2024-09-06. To assist we have created an [example guide for moving to rainbowkit + viem](./migration-notes.md)
5+
46

57
[![MIT License](https://img.shields.io/apm/l/atomic-design-ui.svg?)](https://github.com/celo-org/react-celo/blob/master/LICENSEs)
6-
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/celo-org/react-celo/issues)
78
[![Open Source Love svg1](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/)
89
[![npm version](https://badge.fury.io/js/%40celo%2Freact-celo.png)](https://badge.fury.io/js/%40celo%2Freact-celo)
910
[![codecov](https://codecov.io/gh/celo-org/react-celo/branch/master/graph/badge.svg?token=vy6ALIKLwt)](https://codecov.io/gh/celo-org/react-celo)
@@ -31,14 +32,14 @@ yarn add @celo/react-celo @celo/contractkit
3132

3233
## Supported wallets
3334

34-
- Celo Dance
35-
- Celo Extension Wallet (Metamask fork)
36-
- Celo Terminal
37-
- Celo Wallet
35+
- ~Celo Dance~
36+
- ~Celo Extension Wallet (Metamask fork)~
37+
- ~Celo Terminal~
38+
- ~Celo Wallet~
3839
- Ledger
3940
- MetaMask
4041
- Plaintext private key
41-
- [Omni](https://omni.app)
42+
- ~[Omni](https://omni.app)~
4243
- Valora
4344
- WalletConnect
4445

0 commit comments

Comments
 (0)