Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update guides #18

Merged
merged 1 commit into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading