PayButton
One-click payment button with built-in authentication. Users click, authenticate with their passkey, and the transaction executes.
Usage
import { PayButton } from '@rhinestone/1auth/react';
<PayButton
client={client}
intent={{
targetChain: 8453,
calls: [{ to: '0x...', value: parseEther('0.01') }],
}}
onSuccess={(result) => console.log('Paid:', result.transactionHash)}
onError={(error) => console.error(error)}
/>Props
| Prop | Type | Required | Description |
|---|---|---|---|
client | OneAuthClient | Yes | SDK client instance |
intent | IntentParams | Yes | Transaction parameters |
onSuccess | (result) => void | No | Called on successful transaction |
onError | (error) => void | No | Called on error |
children | ReactNode | No | Button text (default: "Pay with 1auth") |
className | string | No | Custom CSS class |
disabled | boolean | No | Disabled state |
IntentParams
interface IntentParams {
targetChain: number; // Chain ID to execute on
calls: IntentCall[]; // Array of calls to execute
tokenRequests?: TokenRequest[]; // Optional: tokens to receive (output-first)
}
interface IntentCall {
to: `0x${string}`; // Target contract address
value?: bigint; // ETH value to send
data?: `0x${string}`; // Encoded calldata
}
interface TokenRequest {
token: string; // ERC-20 token contract address
amount: bigint; // Amount in base units
}Examples
Simple Payment
<PayButton
client={client}
intent={{
targetChain: 8453,
calls: [{
to: '0xRecipientAddress',
value: parseEther('0.01')
}],
}}
>
Pay $10
</PayButton>Contract Interaction
<PayButton
client={client}
intent={{
targetChain: 8453,
calls: [{
to: contractAddress,
data: encodeFunctionData({
abi: contractAbi,
functionName: 'mint',
args: [tokenId],
}),
value: parseEther('0.05'),
}],
}}
onSuccess={(result) => {
toast.success('NFT minted!');
router.push(`/nft/${tokenId}`);
}}
>
Mint NFT
</PayButton>Custom Styling
<PayButton
client={client}
intent={intent}
className="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-lg"
>
Complete Purchase
</PayButton>ERC20 Payment with tokenRequests
For payments in ERC20 tokens (like USDC), use tokenRequests to tell the orchestrator what tokens are needed. This enables cross-chain funding - users can pay even if their funds are on a different chain.
import { encodeFunctionData, parseUnits } from 'viem';
const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
const amount = parseUnits('10', 6); // 10 USDC
const transferData = encodeFunctionData({
abi: erc20Abi,
functionName: 'transfer',
args: [merchantAddress, amount],
});
<PayButton
client={client}
intent={{
targetChain: 8453, // Base
calls: [{
to: USDC_BASE,
data: transferData,
label: 'Pay Merchant',
sublabel: '10 USDC',
}],
tokenRequests: [{
token: USDC_BASE,
amount: amount,
}],
}}
onSuccess={(result) => toast.success('Payment complete!')}
>
Pay 10 USDC
</PayButton>Chain Abstraction
The user can pay from any chain they have funds on. If their balance is on Arbitrum but targetChain is Base, 1auth automatically bridges the assets. Users see a unified balance and never worry about which chain they're on.