Skip to content

Commit

Permalink
update guides
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasrosario committed May 1, 2024
1 parent 3ea20d3 commit 9b78932
Show file tree
Hide file tree
Showing 8 changed files with 423 additions and 149 deletions.
Binary file modified bun.lockb
Binary file not shown.
308 changes: 204 additions & 104 deletions docs/pages/guides/batch-transactions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,127 +14,227 @@ The actions below are experimental and not supported in most wallets. It is reco

Smart Wallet will submit multiple calls as part of a single transaction. However, if your app supports other wallets, and you want to check that multiple calls will be submitted atomically (in a single transaction), check the wallet's capabilities.

```ts twoslash
import { useWalletClient } from 'wagmi'
import { walletActionsEip5792 } from 'viem/experimental'

const { data: walletClient } = useWalletClient()

if (walletClient) {
const client = walletClient.extend(walletActionsEip5792())
const capabilities = await client.getCapabilities()
// @log: {
// @log: 8453: {
// @log: atomicBatch: {
// @log: supported: true,
// @log: },
// @log: }
// @log: }
:::code-group

```ts twoslash [App.tsx]
// @filename: useEIP5792WalletClient.ts
// [!include ~/snippets/useEIP5792WalletClient.ts]

// @filename: useWalletCapabilities.ts
// [!include ~/snippets/useWalletCapabilities.ts]

// @filename: App.tsx
import React from 'react'
// ---cut---
import { useChainId } from 'wagmi'
import { useWalletCapabilities } from './useWalletCapabilities'

function App() {
const chainId = useChainId()
const { capabilities, loading } = useWalletCapabilities({ chainId })
// @log: {
// @log: atomicBatch: {
// @log: supported: true,
// @log: },
// @log: }

return <div />
}
```

```ts twoslash [useWalletCapabilities.ts]
// @filename: useEIP5792WalletClient.ts
// [!include ~/snippets/useEIP5792WalletClient.ts]

// @filename: useWalletCapabilities.ts
// ---cut---
// [!include ~/snippets/useWalletCapabilities.ts]
```

```ts twoslash [useEIP5792WalletClient.ts]
// [!include ~/snippets/useEIP5792WalletClient.ts]
```

:::

The `getCapabilities` method will return, per chain, the capabilities that the connected wallet supports. If the connected wallet supports atomic batching, it will return an `atomicBatch` capability with a `supported` field equal to `true` for each chain it supports atomic batching on.

### 2. Send the calls

If you have your smart contract ABIs, the easiest way to send multiple calls is to use the Viem `writeContracts` action.

```ts twoslash
import { useWalletClient } from 'wagmi'
import { erc20Abi, parseUnits } from "viem";
import { walletActionsEip5792 } from 'viem/experimental'

const { data: walletClient } = useWalletClient()

if (walletClient) {
const client = walletClient.extend(walletActionsEip5792())
const id = await client.writeContracts({
contracts: [
{
abi: erc20Abi,
address: '0x...', // ERC-20
functionName: 'approve',
args: ['0x...', parseUnits('10', 18)],
},
{
address: '0x...', // Your contract
abi: [], // Your contract ABI
functionName: '...',
args: [],
},
]
})
:::code-group

```ts twoslash [App.tsx]
// @filename: useEIP5792WalletClient.ts
// [!include ~/snippets/useEIP5792WalletClient.ts]

// @filename: useWriteContracts.ts
// [!include ~/snippets/useWriteContracts.ts]

// @filename: App.tsx
import React from 'react'
// ---cut---
import { useAccount } from 'wagmi'
import { useWriteContracts } from './useWriteContracts'

const abi = [
{
stateMutability: 'nonpayable',
type: 'function',
inputs: [{ name: 'to', type: 'address' }],
name: 'safeMint',
outputs: [],
}
] as const

function App() {
const account = useAccount()
const { id, writeContracts } = useWriteContracts()

const handleMint = () => {
writeContracts({
contracts: [
{
address: "0x119Ea671030FBf79AB93b436D2E20af6ea469a19",
abi,
functionName: "safeMint",
args: [account.address],
},
{
address: "0x119Ea671030FBf79AB93b436D2E20af6ea469a19",
abi,
functionName: "safeMint",
args: [account.address],
}
],
})
}

return (
<div>
<button onClick={handleMint}>Mint</button>
{id && <div> ID: {id}</div>}
</div>
)
}
```
The Viem `writeContracts` action will construct the necessary calldata for you, given you provide your smart contract ABIs. You can, however, use the lower level `sendCalls` method if you want to provide the calldata yourself.

```ts twoslash
import { useWalletClient } from 'wagmi'
import { erc20Abi, parseUnits, encodeFunctionData, parseEther } from "viem";
import { walletActionsEip5792 } from 'viem/experimental'

const { data: walletClient } = useWalletClient()

if (walletClient) {
const client = walletClient.extend(walletActionsEip5792())
const id = await client.sendCalls({
calls: [
{
to: '0x...', // ERC-20
data: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: ['0x...', parseUnits('10', 18)],
}),
},
{
to: '0x...', // Your contract
data: '0x...',
value: parseEther('0.001')
},
],
})
}
```ts twoslash [useWriteContracts.ts]
// @filename: useEIP5792WalletClient.ts
// [!include ~/snippets/useEIP5792WalletClient.ts]

// @filename: useWriteContracts.ts
// ---cut---
// [!include ~/snippets/useWriteContracts.ts]
```
```ts twoslash [useEIP5792WalletClient.ts]
// [!include ~/snippets/useEIP5792WalletClient.ts]
```
:::
### 3. Check on the status of your calls
The above `writeContracts` and `sendCalls` examples both return a call bundle identifier. Use the Viem `getCallsStatus` action with this identifier to check on the status of your calls.
The `writeContracts` action returns a call bundle identifier. Use the viem `getCallsStatus` action with this identifier to check on the status of your calls.
This will return a `PENDING` or `CONFIRMED` status along with a subset of a transaction receipt.
```ts twoslash
import { useWalletClient } from 'wagmi'
import { walletActionsEip5792 } from 'viem/experimental'

const { data: walletClient } = useWalletClient()

if (walletClient) {
const client = walletClient.extend(walletActionsEip5792())
// ...
// ...
const status = await client.getCallsStatus({id: '...'}) // The id returned by writeContracts / sendCalls
// @log: {
// @log: status: 'CONFIRMED',
// @log: receipts: [
// @log: {
// @log: logs: [
// @log: {
// @log: address: '0x...',
// @log: topics: [
// @log: '0x...'
// @log: ],
// @log: data: '0x...'
// @log: },
// @log: ],
// @log: status: 'success',
// @log: blockHash: '0x...',
// @log: blockNumber: 122414523n,
// @log: gasUsed: 390000n,
// @log: transactionHash: '0x...'
// @log: }
// @log: ]
// @log: }
:::code-group
```ts twoslash [App.tsx]
// @filename: useEIP5792WalletClient.ts
// [!include ~/snippets/useEIP5792WalletClient.ts]

// @filename: useWriteContracts.ts
// [!include ~/snippets/useWriteContracts.ts]

// @filename: useCallsStatus.ts
// [!include ~/snippets/useCallsStatus.ts]

// @filename: App.tsx
import React from 'react'
// ---cut---
import { useAccount } from 'wagmi'
import { useWriteContracts } from './useWriteContracts'
import { useCallsStatus } from './useCallsStatus'

const abi = [
{
stateMutability: 'nonpayable',
type: 'function',
inputs: [{ name: 'to', type: 'address' }],
name: 'safeMint',
outputs: [],
}
] as const

function App() {
const account = useAccount()
const { id, writeContracts } = useWriteContracts()
const { data: callsStatus, isLoading } = useCallsStatus({ id })
// @log: {
// @log: status: 'CONFIRMED',
// @log: receipts: [
// @log: {
// @log: logs: [
// @log: {
// @log: address: '0x...',
// @log: topics: [
// @log: '0x...'
// @log: ],
// @log: data: '0x...'
// @log: },
// @log: ],
// @log: status: 'success',
// @log: blockHash: '0x...',
// @log: blockNumber: 122414523n,
// @log: gasUsed: 390000n,
// @log: transactionHash: '0x...'
// @log: }
// @log: ]
// @log: }

const handleMint = () => {
writeContracts({
contracts: [
{
address: "0x...",
abi,
functionName: "safeMint",
args: [account.address],
},
{
address: "0x...",
abi,
functionName: "safeMint",
args: [account.address],
}
],
})
}

return (
<div>
<button onClick={handleMint}>Mint</button>
{callsStatus && <div> Status: {callsStatus.status}</div>}
</div>
)
}
```
```
```ts twoslash [useCallsStatus.ts]
// @filename: useEIP5792WalletClient.ts
// [!include ~/snippets/useEIP5792WalletClient.ts]

// @filename: useCallsStatus.ts
// ---cut---
// [!include ~/snippets/useCallsStatus.ts]
```
```ts twoslash [useEIP5792WalletClient.ts]
// [!include ~/snippets/useEIP5792WalletClient.ts]
```
:::
56 changes: 40 additions & 16 deletions docs/pages/guides/magic-spend.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,47 @@ If your app supports Smart Wallet, it should not assume it knows the full balanc
The actions below are experimental and not supported in most wallets. It is recommended to have a fallback mechanism if using this in production.
:::

```ts twoslash
import { useWalletClient } from 'wagmi'
import { walletActionsEip5792 } from 'viem/experimental'

const { data: walletClient } = useWalletClient()

if (walletClient) {
const client = walletClient.extend(walletActionsEip5792())
const capabilities = await client.getCapabilities()
// @log: {
// @log: 8453: {
// @log: auxiliaryFunds: {
// @log: supported: true,
// @log: },
// @log: }
// @log: }
:::code-group

```ts twoslash [App.tsx]
// @filename: useEIP5792WalletClient.ts
// [!include ~/snippets/useEIP5792WalletClient.ts]

// @filename: useWalletCapabilities.ts
// [!include ~/snippets/useWalletCapabilities.ts]

// @filename: App.tsx
import React from 'react'
// ---cut---
import { useChainId } from 'wagmi'
import { useWalletCapabilities } from './useWalletCapabilities'

function App() {
const chainId = useChainId()
const { capabilities, loading } = useWalletCapabilities({ chainId })
// @log: {
// @log: auxiliaryFunds: {
// @log: supported: true,
// @log: },
// @log: }

return <div />
}
```

```ts twoslash [useWalletCapabilities.ts]
// @filename: useEIP5792WalletClient.ts
// [!include ~/snippets/useEIP5792WalletClient.ts]

// @filename: useWalletCapabilities.ts
// ---cut---
// [!include ~/snippets/useWalletCapabilities.ts]
```

```ts twoslash [useEIP5792WalletClient.ts]
// [!include ~/snippets/useEIP5792WalletClient.ts]
```

:::

If your app supports Smart Wallet and sees that the `auxiliaryFunds` capability is supported on a given chain, it means that a user might have funds available for use onchain on Coinbase. As a result, your app should not block user actions on the basis of balance checks.
Loading

0 comments on commit 9b78932

Please sign in to comment.