World Mini App Integration

Integrate Daimo Pay into your World Mini Apps in two ways:

  1. Let users deposit any token from Coinbase, Binance, or other chains into your mini app in seconds.
  2. Interact with contracts on other chains from your mini app, using World Wallet as the source of funds.

Deposit

Enable instant free deposits in your World Mini App with the Daimo Pay Add Money Quick Action. Let your users deposit from Coinbase, Binance, Trust Wallet, or Rainbow Wallet with just a few lines of code.

  • Free: No fees for you or your users.
  • Fast: Deposits complete in seconds.
  • Sponsored swap & bridge costs: Users don't need to pay gas on the destination chain. All swap and bridge costs are sponsored for free.
  • 1:1 stablecoin deposits: For example, users send 1000 USDT on Tron, Solana, or Base, and receive exactly 1000 USDC in your Mini App.
World deposit demo

Here's an example for creating a button that opens the Add Money Quick Action.

page.tsx

export default function Home() {
  const handleClick = () => {
    const baseUrl = 'https://worldcoin.org/mini-app'
    const params = {
      app_id: 'app_e7d27c5ce2234e00558776f227f791ef',
      path: '%2Fbridge',
      toAddress: getAddress('0x03c626f7a66aa72b21870c8031c27a7c2b337b2b'),
      toToken: getAddress('0x79A02482A880bCE3F13e09Da970dC34db4CD24d1'),
      amountUsd: '100',
      sourceAppId: 'app_source1234567890abcdef',
      sourceAppName: 'My%20App',
      sourceDeeplinkPath: '%2Fdashboard',
    }
    const url = `${baseUrl}?${new URLSearchParams(params).toString()}`
    window.open(url, '_blank')
  }

  return (
    <button
      onClick={handleClick}
      className="bg-card flex w-full max-w-md items-center justify-between rounded-2xl border p-4"
    >
      <div className="flex items-center gap-4">
        <img
          src="https://world-id-assets.com/app_e7d27c5ce2234e00558776f227f791ef/04eb7079-e3b1-43a9-8578-ac65c1490adf.png"
          className="h-12 w-12 rounded-xl"
        />

        {/* Text content */}
        <div className="text-left">
          <h3 className="text-lg font-semibold text-gray-800">
            Fund Your Account
          </h3>
          <p className="text-sm text-gray-600">
            Add money to your World Wallet
          </p>
        </div>
      </div>

      <ArrowRight className="h-5 w-5 text-gray-600" />
    </button>
  )
}

Contract Interaction Quickstart

Use WorldPayButton to let users pay or interact with contracts outside World Chain, using their World Wallet. This makes cross-chain calls feel native inside your World Mini App.

Install

Install the required Daimo Pay packages:

npm install @daimo/pay wagmi viem@^2.22.0 @tanstack/react-query

Install the required World MiniKit SDK package:

npm install @worldcoin/minikit-js

Setup

Set up providers for Wagmi, TanStack Query, Daimo Pay, and World MiniKit.

providers.tsx

'use client'
import { DaimoPayProvider, getDefaultConfig } from '@daimo/pay'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { MiniKit } from '@worldcoin/minikit-js'
import { WagmiProvider, createConfig } from 'wagmi'
import React, { useEffect, ReactNode } from 'react'

const wagmiConfig = createConfig(
  getDefaultConfig({
    appName: 'World Mini App Demo',
  }),
)

const queryClient = new QueryClient()

function MiniKitProvider({ children }: { children: ReactNode }) {
  useEffect(() => {
    MiniKit.install()
  }, [])

  return <>{children}</>
}

export function Providers({ children }: { children: ReactNode }) {
  return (
    <MiniKitProvider>
      <WagmiProvider config={wagmiConfig}>
        <QueryClientProvider client={queryClient}>
          <DaimoPayProvider>{children}</DaimoPayProvider>
        </QueryClientProvider>
      </WagmiProvider>
    </MiniKitProvider>
  )
}

Add the Providers component to your application root. Below is an example implementation in a Next.js project.

layout.tsx

import React, { ReactNode } from 'react'
import { Metadata } from 'next'
import { Providers } from './Providers'

import './globals.css'

export const metadata: Metadata = {
  title: 'My World Mini App',
  description: 'One-click contract interaction from any coin on World Chain',
}

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}

Usage

Now that you have your app configured, you can use the WorldPayButton component to allow users to make arbitrary contract calls in one click from their World Wallet.

For example, here is a button that allows users to purchase an NFT on Base using any token in their World Wallet.

page.tsx

'use client'
import { WorldPayButton } from '@daimo/pay'
import { baseETH } from '@daimo/pay-common'
import { encodeFunctionData, getAddress } from 'viem'

export default function Home() {
  return (
    <WorldPayButton
      appId="pay-demo" /* Example Daimo Pay app ID you can use for prototyping */
      worldAppId="<YOUR_WORLD_APP_ID>"
      intent="Purchase NFT"
      toAddress="<YOUR_CONTRACT_ADDRESS>"
      toChain={baseETH.chainId}
      toToken={baseETH.token}
      toUnits="0.0001" /* 0.0001 ETH */
      toCallData={encodeFunctionData({
        abi: YOUR_CONTRACT_ABI,
        functionName: 'mintNFT',
        args: ['<RECIPIENT_ADDRESS>', quantity],
      })}
    />
  )
}

SDK Reference

Use WorldPayButton to allow users to make cross-chain transactions directly from your World Mini App. This component is built for full compatibility with Worldcoin MiniKit.

WorldPayButton Props

  • Name
    appId*
    Type
    string
    Description

    Your Daimo Pay App ID. Use pay-demo for testing.

  • Name
    worldAppId*
    Type
    string
    Description

    Your World Mini App ID, obtained from the Worldcoin developer dashboard.

  • Name
    intent
    Type
    string
    Description

    The intent verb, such as "Pay with World", "Mint NFT", 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.

  • 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, if toCallData is specified, then the payment amount will be approved to the destination toAddress immediately before calling the contract. Otherwise, the amount will be transferred to toAddress.

  • 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 of toUnits to the contract before executing the call.

  • 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
    refundAddress
    Type
    string
    Description

    Optional fallback address for refunds if the payment bounces.

import { encodeFunctionData } from "viem";

<WorldPayButton
  {/* Required props */}
  appId="pay-demo"
  worldAppId="YOUR_WORLD_APP_ID"
  toAddress="0x1234567890123456789012345678901234567890"
  toChain={8453} // Base
  toUnits="1.00" // $1, Base USDC
  toToken="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" // Base USDC

  {/* Optional props */}
  intent="Purchase NFT"
  toCallData={encodeFunctionData({ // Example contract call
    abi: YOUR_CONTRACT_ABI,
    functionName: "mintNFT",
    args: ["RECIPIENT_ADDRESS", quantity],
  })}
  externalId="123"
  metadata={{ mySystemId: "123", name: "John Doe" }}
/>

WorldPayButton.Custom

In addition, you can replace the WorldPayButton entirely with your own button using WorldPayButton.Custom.

  • Name
    children*
    Type
    function
    Description

    Custom renderer function that receives show and hide methods which control the modal visibility. Return a React node.

<WorldPayButton.Custom
  appId="pay-demo"
  worldAppId="YOUR_WORLD_APP_ID"
  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>}
</WorldPayButton.Custom>

Was this page helpful?