Skip to content

Commit

Permalink
docs: add a migration guide (#363)
Browse files Browse the repository at this point in the history
* docs: add a migration guide

* notice about deprecation on readme

* upgrade guide for v2

* add link and set date

---------

Co-authored-by: Aaron DeRuvo <[email protected]>
  • Loading branch information
nicolasbrugneaux and aaronmgdr authored Jun 6, 2024
1 parent 004161b commit 8bc5bfb
Show file tree
Hide file tree
Showing 2 changed files with 286 additions and 7 deletions.
278 changes: 278 additions & 0 deletions migration-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
# Draft: Migration document from react-celo to rainbowkit

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)

## Requirements

```bash
npm install @rainbow-me/rainbowkit@2 wagmi@2 [email protected] @tanstack/react-query
```

Optional recommended packages

```bash
npm install @celo/abis
```

## Initialization

```ts
// react-celo
import { CeloProvider } from '@celo/react-celo';
import '@celo/react-celo/lib/styles.css';

function WrappedApp() {
return (
<CeloProvider
dapp={{
name: 'My awesome dApp',
description: 'My awesome description',
url: 'https://example.com',
// 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
walletConnectProjectId: '123',
}}
>
<App />
</CeloProvider>
);
}
```

```ts
// rainbowkit
import '@rainbow-me/rainbowkit/styles.css'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { WagmiProvider, http } from 'wagmi'
import { celo, celoAlfajores } from 'wagmi/chains';
import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
import { getDefaultConfig } from '@rainbow-me/rainbowkit'

const config = getDefaultConfig({
appName: 'Your app',
projectId: 'YOUR_PROJECT_ID',
chains: [celo, celoAlfajores],
transports: {
[celo.id]: http(),
[celoAlfajores.id]: http(),
},
})

function WrappedApp() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>
{/* Your App */}
</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}
```

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.

For example:

```diff
import { configureChains } from 'wagmi';
- import { celo, celoAlfajores } from 'wagmi/chains';
+ import { celo, celoAlfajores, avalanche, mainnet } from 'wagmi/chains';

const { chains, publicClient } = configureChains(
- [celo, celoAlfajores],
+ [celo, celoAlfajores, mainnet, avalanche],
...
);
```

## Basic usage

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.

### Connecting your dapp to a wallet

```ts
// react-celo
import { useCelo } from '@celo/react-celo';

function App() {
const { connect, address } = useCelo();

return (
<>
{address ? (
<div>Connected to {address}</div>
) : (
<button onClick={connect}>Connect wallet</button>
)}
</>
);
}
```

```ts
// rainbowkit
import { ConnectButton } from '@rainbow-me/rainbowkit';

function App() {
const { connect, address } = useCelo();

return <ConnectButton />;
}
```

More details regarding the connect button `props` in the [rainbowkit docs](https://www.rainbowkit.com/docs/connect-button)

### Reading chain data

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.

```ts
// ./use-celo-registry-address.ts
// Helper to interact with the celo registry, abstracted in contractkit
// We will probably add it to rainbowkit-celo, but until then, feel free
// to copy the following snippet in your codebase
import { useContractRead } from 'wagmi';
import { registryABI } from '@celo/abis/types/wagmi';

export default function useCeloRegistryAddress(contractName: string) {
const { data: address } = useContractRead({
address: '0x000000000000000000000000000000000000ce10', // constant on mainnet and alfajores
abi: registryABI,
functionName: 'getAddressForString',
args: [contractName],
});

if (address && parseInt(address, 16) === 0) {
return undefined;
}
return address;
}
```

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.

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.

```diff
- import { useCelo } from '@celo/react-celo';
+ import { useAccount } from 'wagmi';
+ import { accountsABI } from '@celo/abis/types/wagmi';
+ import useCeloRegistryAddress from './use-celo-registry-address';

+ function useAccountSummary() {
+ const { isConnected, address } = useAccount();
+ const { data: accountSummary } = useContractRead({
+ address: useCeloRegistryAddress('Accounts'),
+ abi: accountsABI,
+ functionName: 'getAccountSummary',
+ });
+
+ return accountSummary
+ }

function App() {
- const { kit, address } = useCelo();
-
- async function getAccountSummary() {
- const accounts = await kit.contracts.getAccounts();
- await accounts.getAccountSummary(address);
- }
+ const accountSummary = useAccountSummary();

return (
...
)
}
```

### Send a transaction

```ts
// react-celo
import { useCelo } from '@celo/react-celo';

function App() {
const { performActions } = useCelo();

async function transfer() {
await performActions(async (kit) => {
const cUSD = await kit.contracts.getStableToken();
await cUSD.transfer('0x...', 10000).sendAndWaitForReceipt();
});
}

return <button onClick={transfer}>Transfer</button>;
}
```

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`.

```ts
// rainbowkit
import { usePrepareContractWrite, useContractWrite } from 'wagmi';
import { StableTokenABI } from '@celo/abis/types/wagmi';
import useCeloRegistryAddress from './use-celo-registry-address';
// optional
import MyCustomModal from './modal';

function App() {
// optional modal state
const [isOpen, setIsOpen] = useState(false);

const { config } = usePrepareContractWrite({
address: useCeloRegistryAddress('StableToken'),
abi: StableTokenABI,
functionName: 'transfer',
args: ['0x...', 10000],
onSettle: () => setIsOpen(false),
});
const { write } = useContractWrite(config);
const transfer = useCallback(() => {
setIsOpen(true);
write();
}, [write]);

return;
<>
<button onClick={transfer}>Transfer</button>
{isOpen && <MyCustomModal />}
</>;
}
```

### Fee currency

While react-celo provides a `feeCurrency` variable and an `updateFeeCurrency` helper method, this isn't the case for rainbowkit. However, [email protected]+ also supports `feeCurrency` out of the box thanks to its Celo-specific block and transactions formatters.

```tsx

import { useSendTransaction } from 'wagmi'

function App() {
const { sendTransaction } = useSendTransaction()

return (
<button
onClick={() =>
sendTransaction({
to: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
value: parseEther('0.01'),
feeCurrency: '<USDC TOKEN ADDRESS HERE>'
})
}
>
Send transaction
</button>
)
}

```

## Further reading

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)!

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).
15 changes: 8 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# react-celo

(_Formerly known as use-contractkit. [read the upgrade guide](/guides/migrate-to-v4.md)_)
> [!CAUTION]
> 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)

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

## Supported wallets

- Celo Dance
- Celo Extension Wallet (Metamask fork)
- Celo Terminal
- Celo Wallet
- ~Celo Dance~
- ~Celo Extension Wallet (Metamask fork)~
- ~Celo Terminal~
- ~Celo Wallet~
- Ledger
- MetaMask
- Plaintext private key
- [Omni](https://omni.app)
- ~[Omni](https://omni.app)~
- Valora
- WalletConnect

Expand Down

0 comments on commit 8bc5bfb

Please sign in to comment.