Daimo Pay SDK
The best way to embed Daimo Pay into your app is via the @daimo/pay
SDK.
The SDK is open source. You can find it on NPM and GitHub. For installation instructions, see the Quickstart. For a live demo of common use-cases, see the DaimoPayButton Demo. For details, see below.

DaimoPayButton Reference
- Name
appId
*- Type
- string
- Description
Your public app ID. Use
pay-demo
for prototyping only.
- Name
intent
- Type
- string
- Description
The intent verb, such as "Pay", "Deposit", or "Purchase".
- Name
toAddress
*- Type
- string
- Description
The destination address to transfer to, or contract to call.
- Name
toChain
*- Type
- number
- Description
The destination chain ID
toAddress
is on.
- Name
toUnits
- Type
- string
- Description
Controls the exact amount to receive. Must be a precise decimal string (e.g. "1.00" for $1.00 USDC). Providing more decimals than the underlying token supports will result in an error.
When specified: User pays a fixed amount. You receive exactly this amount, with no rounding from fees or slippage. Ideal for checkouts.
When omitted: User can input any amount to send. Ideal for deposits or top-ups into your app.
- Name
toToken
*- Type
- string
- Description
The destination token to send, completing payment. Must be an ERC-20 token or the zero address
0x0000000000000000000000000000000000000000
, indicating the native token such as ETH. For ERC-20, iftoCallData
is specified, then the payment amount will be approved to the destinationtoAddress
immediately before calling the contract. Otherwise, the amount will be transferred totoAddress
.
- Name
toCallData
- Type
- string
- Description
Optional calldata to execute an arbitrary contract call if
toAddress
is a contract. If specified, we'll automatically make a token approval oftoUnits
to the contract before executing the call.
- Name
paymentOptions
- Type
- string[]
- Description
Optional filter to show only a subset of payment options. By default, all are enabled. The available options are:
Coinbase
,Binance
,Solana
,RampNetwork
, andExternalChains
.ExternalChains
includes Bitcoin, Tron, Zcash, and other non-EVM chains. With these options, even users with no crypto wallet can complete payment.
- Name
preferredChains
- Type
- number[]
- Description
Optional preferred chain IDs. Assets on these chains will appear first.
- Name
preferredTokens
- Type
- object[]
- Description
Optional preferred tokens. Assets in these specific tokens will appear first, taking precedence over
preferredChains
. Each token has the format:{ chain: number, address: string }
.
- Name
externalId
- Type
- string
- Description
Optional. Associates this payment with an external ID, such as your system's unique checkout or deposit ID. Passed in webhooks and returned in API responses.
Multiple calls with the same
externalId
will return the same Payment instead of creating new ones. This prevents accidentally creating duplicate payments.
- Name
metadata
- Type
- object
- Description
Optional. Attach key-value data to the payment object that persists across webhooks and API responses. For example, attach your system’s unique ID to simplify tracking, or store customer information with their payment.
You can specify up to 50 key-value pairs. Keys and values are stored as strings.
- Name
redirectReturnUrl
- Type
- string
- Description
Optional. Redirect URL to return to the app. After the user pays with Coinbase, Binance, or RampNetwork, they will be redirected back to this URL.
- Name
closeOnSuccess
- Type
- boolean
- Description
Optional. If set, automatically closes the modal after a successful payment.
- Name
resetOnSuccess
- Type
- boolean
- Description
Optional. If set, automatically resets the payment after a successful transaction, using the original props. This allows the user to initiate a new payment without refreshing the page.
import { encodeFunctionData } from "viem";
<DaimoPayButton
{/* Required props */}
appId="pay-demo"
toAddress="0x1234567890123456789012345678901234567890"
toChain={10} /* Optimism */
toUnits="1.00" /* $1, Optimism USDC */
toToken="0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" /* Optimism USDC */
{/* Optional props */}
intent="Purchase NFT"
toCallData={encodeFunctionData({ /* Example contract call */
abi: YOUR_CONTRACT_ABI,
functionName: "mintNFT",
args: ["RECIPIENT_ADDRESS", quantity],
})}
paymentOptions={["Coinbase", "Binance"]}
preferredChains={[10, 8453]} // Prefer Optimism, Base
preferredTokens={[ // Prefer Optimism USDC
{ chain: 10, address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" }
]},
externalId="123",
metadata={{ mySystemId: "123", name: "John Doe" }}
{/* Event handlers */}
onPaymentStarted={(e) => console.log(e)}
onPaymentCompleted={(e) => console.log(e)}
onPaymentBounced={(e) => console.log(e)}
/>
Modifying Payment Parameters
Once the DaimoPayButton
is rendered, its payment parameters are frozen to
ensure a consistent and predictable user experience. This means that changes to
props like toUnits
or toAddress
after initial render will not automatically
update the current payment.
If your app needs to dynamically update the payment — such as when the user
changes the amount, selects a different token, or switches networks — you can
use the resetPayment
function provided by the useDaimoPayUI
hook.
Calling resetPayment
updates the current payment parameters. It accepts the
same parameters as DaimoPayButton
. You can pass only the props you wish to
change; any omitted fields will retain their previous values.
import { useDaimoPayUI } from "@daimo/pay";
const { resetPayment } = useDaimoPayUI();
// Example: user selects a new amount and token
function handleAmountChange(newAmount: string) {
resetPayment({
toChain: 8453, // Base
toUnits: newAmount, // updated amount
toToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // Base USDC
});
}
Themes and Customization
You can customize the appearance of both the button and the modal according to
preset themes or using customTheme
.
- Name
mode
- Type
- string
- Description
Light mode, dark mode, or auto.
- Name
theme
- Type
- string
- Description
Named theme. See docs for options.
- Name
customTheme
- Type
- object
- Description
Custom theme. See docs for options.
- Name
disabled
- Type
- boolean
- Description
Disable interaction.
<DaimoPayButton
appId="pay-demo"
toAddress="0x1234567890123456789012345678901234567890"
toChain={8453} // Base
toUnits="0.001" // 0.001 ETH
toToken="0x0000000000000000000000000000000000000000"
mode="dark"
theme="rounded"
{/* alternatively, customTheme={...} */}
/>
Event Handlers
- Name
onPaymentStarted
- Type
- function
- Description
Called when the user sends payment and the transaction is seen on-chain.
- Name
onPaymentCompleted
- Type
- function
- Description
Called when the destination transfer or call completes successfully.
- Name
onPaymentBounced
- Type
- function
- Description
Called when the destination call reverts and funds are refunded.
- Name
onOpen
- Type
- function
- Description
Called when the payment modal opens. Useful for analytics or UI transitions.
- Name
onClose
- Type
- function
- Description
Called when the payment modal closes, whether from user dismissal or after a completed payment.
The events passed to the onPayment...
handlers match the events passed to
webhooks. You can use them for immediate feedback, while using
webhooks for things like backend order status tracking. This ensures robust
tracking even if the user loses network during payment.
const [latest, setLatest] = useState<DaimoPayEvent>();
return (<>
<DaimoPayButton
{/* For existing payments created via API, use payId. */}
payId="72hebvwpDJDA9qNubzb2jYjAbdDgjH4uD53rBnh8BR3A"
{/* Either way, the onPayment... handlers always work. */}
onPaymentStarted={setLatest}
onPaymentCompleted={setLatest}
onPaymentBounced={setLatest}
onOpen={() => console.log("Modal opened")}
onClose={() => console.log("Modal closed")}
/>
{latest.type === 'payment_started' && <Spinner />}
{latest.type === 'payment_completed' && <SuccessLink txHash={latest.txHash} />}
{latest.type === 'payment_bounced' && <RevertLink txHash={latest.txHash} />}
</>);
DaimoPayButton.Custom
In addition, you can replace the DaimoPayButton entirely with your own button using DaimoPayButton.Custom.
- Name
children
*- Type
- function
- Description
Custom renderer function that receives show/hide methods and returns React node.
<DaimoPayButton.Custom
appId="pay-demo"
toAddress="0x1234567890123456789012345678901234567890"
toChain={10} /* Optimism */
toUnits="1.23" /* $1.23 Optimism USDC */
toToken="0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" /* Optimism USDC */
>
{({ show, hide }) => <button onClick={show}>Custom Pay Button</button>}
</DaimoPayButton.Custom>
Configuration Reference
The @daimo/pay
SDK uses a configuration object to set up providers for your
application. This configuration is essential for initializing the SDK and
ensuring compatibility with the supported chains and transports. Below is a
detailed reference to the configuration options available in defaultConfig
.
defaultConfig
Parameters
- Name
appName
- Type
- string
- Description
The name of your application. This is displayed to users during wallet connections and other interactions. Default is "Daimo Pay".
- Name
appIcon
- Type
- string
- Description
Optional URL pointing to the app's icon. Used in wallet connection UIs.
- Name
appDescription
- Type
- string
- Description
Optional description of your app. Shown to users in wallet connection prompts.
- Name
appUrl
- Type
- string
- Description
Optional URL of your app. Used in wallet connection interfaces.
- Name
ssr
- Type
- boolean
- Description
Indicates whether the app uses server-side rendering (SSR). Set to
true
for SSR-enabled projects. Default isfalse
.
- Name
walletConnectProjectId
- Type
- string
- Description
Optional WalletConnect Project ID. Tracks usage statistics and ensures proper connection. Defaults to Daimo's WalletConnect Project ID.
- Name
connectors
- Type
- function[]
- Description
Specifies wallet connectors. Defaults to Daimo's recommended connectors and configurations. Will override all default connectors and
additionalConnectors
.
- Name
additionalConnectors
- Type
- function[]
- Description
Optional additional wallet connectors to use in the configuration. Extend the list of default connectors with custom wallet connectors.
- Name
transports
- Type
- object
- Description
Defines the network transport (e.g., HTTP) for each supported chain. If not provided, default wagmi HTTP transports are used.
import { getDefaultConfig } from "@daimo/pay";
import { createConfig, http } from "wagmi";
import { mainnet, optimism } from "wagmi/chains";
// Define your configuration
const config = createConfig(
getDefaultConfig({
appName: "My Ethereum App",
appIcon: "https://example.com/icon.png",
appDescription: "An app for seamless crypto payments",
appUrl: "https://example.com",
walletConnectProjectId: "your-project-id", // Replace with your WalletConnect Project ID
additionalConnectors: [], // Add custom wallet connectors here
transports: {
[mainnet.id]: http("https://eth.llamarpc.com"),
[optimism.id]: http("https://optimism-rpc.publicnode.com"),
},
}),
);