ガイド
ERC20でガスを支払う
Web SDKを使ってERC20でガスを支払う方法を学びましょう。
1
Web SDKのセットアップ
はじめにガイドを完了してください。
2
ETHで支払う基本的な非スポンサー取引
次に、ユーザーがスマートウォレットのネイティブ通貨で非スポンサー取引を送信できるシンプルなページを作成します。ここでは特別なことはありません。
import React from 'react';
import { useAccount, useSendTransaction } from 'wagmi';
export const ERC20GasPaymentExample = () => {
const { address } = useAccount();
const {
sendTransaction,
isPending,
isSuccess,
data: txHash
} = useSendTransaction();
const sendUnsponsored = () => {
if (!address) return;
// Send a simple 0 value transaction to yourself
sendTransaction({
to: address,
value: BigInt(0),
gas: null
});
};
return (
<>
<div>
<p>Address: {address}</p>
<button onClick={sendUnsponsored}>Send Unsponsored</button>
{isPending && <p>Pending...</p>}
{isSuccess && <p>Success! Tx Hash: {txHash}</p>}
</div>
</>
)
}
3
ガスをERC20トークンで支払ってみましょう
useWaasFeeOptions
フックを使って、ユーザーがERC20でガスを支払えるようにします。
内部的には、WaaSコネクタがこの取引リクエストをインターセプトし、手数料確認フローを開始します。
useWaasFeeOptions
フックを宣言したことで、WaaSプロバイダーのデフォルトのfeeConfirmationHandler
が上書きされ、ERC20トークンでの支払いが可能になりました。
import React, { useState, useEffect } from 'react';
import { useWaasFeeOptions } from '@0xsequence/connect';
import { useAccount, useSendTransaction } from 'wagmi';
export const ERC20GasPaymentExample = () => {
const { address } = useAccount();
const [pendingFeeOptionConfirmation, confirmPendingFeeOption] = useWaasFeeOptions();
const {
sendTransaction,
isPending,
isSuccess,
data: txHash
} = useSendTransaction();
const [selectedFeeTokenName, setSelectedFeeTokenName] = useState<string>();
useEffect(() => {
if (pendingFeeOptionConfirmation && pendingFeeOptionConfirmation.options.length > 0) {
setSelectedFeeTokenName(pendingFeeOptionConfirmation.options[0].token.name);
}
}, [pendingFeeOptionConfirmation]);
const sendUnsponsored = () => {
if (!address) return;
// Send a simple 0 value transaction to yourself
sendTransaction({
to: address,
value: BigInt(0),
gas: null
});
};
return (
<>
<div>
<p>Address: {address}</p>
<button onClick={sendUnsponsored}>Send Unsponsored</button>
{isPending && <p>Pending...</p>}
{isSuccess && <p>Success! Tx Hash: {txHash}</p>}
</div>
</>
)
}
この例では最初のオプションをデフォルトにしていますが、次のステップでユーザーが支払いたい手数料トークンを選択できるUIを追加します。
4
手数料トークンセレクター(UI)の追加
次に、ユーザーが支払いたい手数料トークンを選択できる手数料トークンセレクターを追加します。
各手数料オプションにはhasEnoughBalanceForFee
というブール値プロパティがあり、ユーザーが手数料を支払うのに十分な残高があるかどうかを知らせることができます。また、balance
プロパティにはそのトークンの残高が含まれています。
import { useState, useEffect } from 'react';
import { useWaasFeeOptions } from '@0xsequence/connect';
import { formatUnits } from 'viem';
import { useAccount, useSendTransaction } from 'wagmi';
export const ERC20GasPaymentExample = () => {
const { address } = useAccount();
// 1. Set up the fee options hook
const [pendingFeeOptionConfirmation, confirmPendingFeeOption, rejectPendingFeeOption] = useWaasFeeOptions();
// 2. Set up transaction hook
const {
sendTransaction,
isPending,
isSuccess,
data: txHash
} = useSendTransaction();
// 3. Track selected fee token
const [selectedFeeTokenName, setSelectedFeeTokenName] = useState<string>();
// 4. Initialize with first option when fee options become available
useEffect(() => {
if (pendingFeeOptionConfirmation && pendingFeeOptionConfirmation.options.length > 0) {
setSelectedFeeTokenName(pendingFeeOptionConfirmation.options[0].token.name);
}
}, [pendingFeeOptionConfirmation]);
// 5. Function to send an unsponsored transaction
const sendUnsponsored = () => {
if (!address) return;
// Send a dummy tx
sendTransaction({
to: address,
value: BigInt(0),
gas: null
});
};
return (
<div className="card padding-4 flex-direction-column gap-4 max-width-500px margin-0 auto">
<div className="card padding-4">
<p className="text-large font-bold margin-bottom-4">
ERC20 Gas Payment Example
</p>
<button
onClick={sendUnsponsored}
className="button-primary"
disabled={isPending}
>
{isPending ? 'Sending Transaction...' : 'Send Transaction'}
</button>
{isSuccess && txHash && (
<div className="card margin-y-4 padding-3 background-positive border-radius-md">
<p>Transaction successful! Hash: {txHash}</p>
</div>
)}
{/* Fee selection UI appears when needed */}
{pendingFeeOptionConfirmation && (
<div className="card margin-top-4 flex-direction-column gap-3">
<p className="font-semibold">
Select Token to Pay Gas Fees
</p>
<select
name="feeOption"
value={selectedFeeTokenName}
onChange={(e) => setSelectedFeeTokenName(e.target.value)}
className="w-full p-2 rounded-lg bg-gray-700 text-white border border-gray-600"
>
{pendingFeeOptionConfirmation.options.map(option => (
<option key={option.token.name} value={option.token.name}>
{option.token.name} - Fee: {formatUnits(BigInt(option.value), option.token.decimals || 18)} {option.token.symbol}
</option>
))}
</select>
<div className="card flex-direction-row gap-2 justify-end">
<button
className="button-secondary"
onClick={() => rejectPendingFeeOption(pendingFeeOptionConfirmation.id)}
>
Cancel
</button>
<button
className="button-primary"
onClick={() => {
const selected = pendingFeeOptionConfirmation.options.find(
option => option.token.name === selectedFeeTokenName
);
if (selected && selected.token.contractAddress) {
confirmPendingFeeOption(
pendingFeeOptionConfirmation.id,
selected.token.contractAddress
);
}
}}
>
Confirm
</button>
</div>
</div>
)}
</div>
</div>
);
};
おめでとうございます!Web SDKを使ってERC20でガスを支払う方法を学びました。