Mobile (WalletConnect)

Quick Start: WalletConnect

Connect your web app to Joey Wallet on mobile with @joey-wallet/wc-client and send your first sign request.

This guide connects a Next.js app to the Joey mobile app over WalletConnect using @joey-wallet/wc-client. Building for the desktop browser extension instead? See the browser extension quick start.

Tip

Already have WalletConnect in your app? You don't need wc-client. See Add to an existing project.

1. Install

pnpm add @joey-wallet/wc-client

Note

@joey-wallet/wc-client 1.0.4 requires React 19 (react and react-dom ^19).

2. Get a Reown project ID

Create a project on the Reown dashboard and copy its Project ID. Store it in an environment variable such as NEXT_PUBLIC_PROJECT_ID.

3. Create a configuration file

// src/app/config.ts
import type { Config } from '@joey-wallet/wc-client';

export default {
  // Required: your Reown project ID
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID,
  // Optional: shown to the user in Joey when they connect
  metadata: {
    name: 'Joey Example Project',
    description: 'A sample project using WalletConnect and Joey Wallet.',
    url: 'http://localhost:3000',
    icons: ['http://localhost:3000/favicon.ico'],
    redirect: {
      universal: 'http://localhost:3000',
    },
  },
} as Config;

See Configuration for every option.

4. Wrap your app in the provider

// src/app/provider.tsx
'use client';

import * as React from 'react';
import { advanced } from '@joey-wallet/wc-client/react';
import config from './config';

const { Provider: WcProvider, useProvider } = advanced.default;
export { useProvider };

export function Provider({ children }: React.PropsWithChildren) {
  return <WcProvider config={config}>{children}</WcProvider>;
}

Render <Provider> around the pages that need the wallet.

5. Connect

// src/app/connect-button.tsx
'use client';

import { useProvider } from './provider';

export function ConnectButton() {
  const { actions, session, accounts } = useProvider();

  const handleConnect = async () => {
    const { error } = await actions.connect();
    if (error) throw error;
  };

  if (session) {
    return (
      <div>
        <p>Connected</p>
        {accounts?.map((account) => <div key={account}>{account}</div>)}
      </div>
    );
  }
  return <button onClick={handleConnect}>Connect</button>;
}

connect() opens the WalletConnect modal. The user scans the QR code with Joey (or taps through on mobile) and approves the connection. Accounts are returned as xrpl:<chain>:<address>, for example xrpl:0:rExample….

6. Send a sign request

// src/app/send-button.tsx
'use client';

import * as React from 'react';
import type { Payment } from 'xrpl';
import core from '@joey-wallet/wc-client/core';
import { useProvider } from './provider';

export function SendButton() {
  const { provider, chain, accounts } = useProvider();
  const [result, setResult] = React.useState<string>();

  const handleSend = async () => {
    if (!provider || !chain) throw new Error('Not connected');
    const address = accounts?.[0]?.split(':')[2];
    if (!address) throw new Error('No connected account');

    const tx_json: Payment = {
      TransactionType: 'Payment',
      Account: address,
      Destination: 'ra5nK24KXen9AHvsdFTKHSANinZseWnPcX',
      Amount: '1000000', // 1 XRP, in drops
    };

    const response = await core.methods.signTransaction({
      provider,
      chainId: chain,
      request: { tx_json, options: { autofill: true, submit: true } },
    });
    setResult(JSON.stringify(response, null, 2));
  };

  return (
    <>
      <button onClick={handleSend}>Send 1 XRP</button>
      {result && <pre>{result}</pre>}
    </>
  );
}

Joey fills in Fee, Sequence and LastLedgerSequence, shows the user a review, then signs and submits. The response contains the signed transaction and its hash; use the hash to confirm the result on-ledger.

Next steps