Checkout
Use PayButton to authenticate with a passkey and submit a payment intent.
Using PayButton
PayButton handles authentication, signing, and execution.
Install the SDK
npm install @rhinestone/1authCreate client.ts
Create the client:
import { OneAuthClient } from '@rhinestone/1auth'
// Create the 1auth client
export const client = new OneAuthClient({
providerUrl: 'https://passkey.1auth.app',
clientId: 'my-app',
}) Checkout flows that already show payment details use blind signing by default. Enable experimental clear signing on the shared client to show 1auth's review UI:
export const client = new OneAuthClient({
providerUrl: 'https://passkey.1auth.app',
clientId: 'my-app',
experimental_clear_signing: true,
})Add PayButton
Render PayButton:
Handle success
Use onSuccess for post-payment work:
Handle failures
PayButton converts structured sendIntent() result failures to
OneAuthError, preserving their machine-readable code and provider diagnostics.
Other caught exceptions can still reach onError as generic Error objects,
so keep the fallback branch shown below.
import { OneAuthError, PayButton } from '@rhinestone/1auth/react'
const handleError = (error: Error) => {
if (error instanceof OneAuthError) {
console.error('Payment failed', {
code: error.code,
providerCode: error.details?.providerCode,
traceId: error.details?.traceId,
simulationUrls: error.details?.simulationUrls,
})
return
}
console.error('Payment failed', error)
}
<PayButton client={client} intent={intent} onError={handleError}>
Complete Purchase
</PayButton>Use INVALID_SIGNATURE to route the user to account recovery. For
PREPARE_FAILED or EXECUTE_FAILED, keep traceId and simulationUrls in
developer logs so the failed quote or simulation can be investigated.
Contract interactions
PayButton also accepts contract calls:
import { encodeFunctionData } from 'viem'
<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!')}
>
Mint NFT
</PayButton>Custom styling
Use className for custom styles:
<PayButton
client={client}
intent={intent}
className="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-lg"
>
Complete Purchase
</PayButton>Props reference
| Prop | Type | Required | Description |
|---|---|---|---|
client | OneAuthClient | Yes | SDK client instance |
intent | SendIntentOptions | Yes | Transaction parameters (calls, targetChain, tokenRequests) |
onSuccess | (result: SendIntentResult) => void | No | Called on successful transaction |
onError | (error: Error) => void | No | Called on error |
closeOn | CloseOnStatus | No | When to close dialog: "claimed", "preconfirmed", "filled", or "completed". Default: "preconfirmed" |
children | ReactNode | No | Button text (default: "Pay with 1auth") |
className | string | No | Custom CSS class |
style | React.CSSProperties | No | Custom inline styles (merged with defaults) |
disabled | boolean | No | Disabled state |
hideIcon | boolean | No | Hide the fingerprint icon |
See the full PayButton API reference for more details.
Next steps
- Crosschain - Execute transactions on any chain
- Batch Transactions - Queue multiple operations