Skip to content

WalletConnect Adapter ​

WalletConnect connects compatible XRPL wallets using WalletConnect v2, QR codes and wallet deep links. Choose a generic WalletConnect entry or separate entries for supported wallet configurations.

IntegrationValue
Package@xrpl-wallet-kit/adapter-walletconnect
Adapter IDwalletconnect; detail entries use wallet-specific IDs
Wallet typeWalletConnect protocol
Client registrationIncluded when walletConnectProjectId is provided

Installation ​

sh
npm install @xrpl-wallet-kit/core @xrpl-wallet-kit/adapter-walletconnect xrpl@^4

For the Client tab below, install @xrpl-wallet-kit/client instead. Obtain a project ID from WalletConnect Cloud.

Connect ​

ts
import { createWalletKit } from "@xrpl-wallet-kit/client";

const kit = createWalletKit({
  network: "mainnet",
  wallets: ["walletconnect"],
  walletConnectProjectId: "YOUR_WALLETCONNECT_PROJECT_ID",
});
const { manager } = kit;
const { account } = await kit.connect("walletconnect");
ts
import { WalletManager } from "@xrpl-wallet-kit/core";
import { createWalletConnectAdapter } from "@xrpl-wallet-kit/adapter-walletconnect";

const manager = new WalletManager({
  network: "mainnet",
  adapters: [createWalletConnectAdapter({
    projectId: "YOUR_WALLETCONNECT_PROJECT_ID",
    metadata: {
      name: "My dApp", description: "My XRPL dApp",
      url: "https://my-dapp.example", icons: [],
    },
  })],
});
const { account } = await manager.connect("walletconnect");

Start connection from a user action. The default factory uses AppKit's QR modal on desktop and mobile. Approve the dApp and requested network in the chosen wallet.

Networks ​

The standard XRPL presets use xrpl:0 (Mainnet), xrpl:1 (Testnet) and xrpl:2 (Devnet). The wallet must approve the requested chain and methods. Custom network definitions need a valid walletConnectChainId. Xahau is not supported by this adapter.

Capabilities ​

These are adapter operations; actual signing support also depends on the connected wallet and approved session.

OperationSupport
ConnectYes
DisconnectYes
Session restoreGeneric entry only, with an active stored session; detail entries reconnect explicitly
signTransaction()Yes, if the wallet returns a signed blob without submitting
signAndSubmit()Yes
signMessage()Enabled by default; signedTx proof, wallet support required
signIn()Not exposed
switchNetwork()Not exposed; reconnect for the requested chain
Payment / NFT transactionsGeneric txJson; connected wallet dependent
QR / deep linkYes; depends on modal mode and wallet configuration

Options ​

These options apply to createWalletConnectAdapter(). The client helper exposes walletConnectProjectId, app metadata and ui.walletConnect; supply configured adapters for lower-level control.

OptionTypeDefaultDescription
projectIdstringRequiredWalletConnect project ID
useModalbooleantrueUse AppKit's built-in modal
modalMode"always", "mobile-only" or "never""always"Where AppKit is shown; custom QR is used otherwise
metadataSignClientTypes.MetadataNot setdApp name, description, URL and icons
themeMode"light" or "dark"AppKit defaultAppKit appearance
signMessagebooleantrueEnable Kit's message-proof signing operation
signMessageDestinationstringConnected accountDestination for the sign-only message-proof Payment
deeplink(uri: string) => stringWallet-specificBuild a wallet deep link
onQr(event) => voidNot setReceive the URI for custom QR UI
id / namestringwalletconnect / WalletConnectAdapter identity/display name
iconstringEmbedded WalletConnect iconCustom icon URL or data URI
requestTimeoutMsnumber120000Connection handshake timeout
signRequestTimeoutMsnumberRequest/adapter policyOverride signing timeout
signClientSignClientCreated on demandExisting WalletConnect client
recoveryStorageWalletStorageBrowser storagePending recovery markers
onDebug(event: WalletConnectDebugEvent) => voidNot setOptional adapter diagnostics

Defaults above describe the singular factory; detail-mode entries can select their own modal/deep-link defaults.

Transactions ​

These XRPL examples use manager and account from either Connect tab. Run each request separately from a user action. Replace recipient addresses and 64-character NFT/offer IDs before signing. Amounts are in drops: "1000000" is 1 XRP. Include DestinationTag when the recipient requires it.

maxFeeDrops is an application-selected ceiling, not the expected fee. Adjust the example limit for your application.

A returned hash or submitted status is not validated ledger confirmation. Check the transaction result before treating a payment or NFT transfer as complete. See WalletManager Events.

Payment ​

ts
const result = await manager.signAndSubmit({
  txJson: {
    TransactionType: "Payment",
    Account: account.address,
    Destination: "<recipient_address>",
    Amount: "1000000",
  },
  maxFeeDrops: "50000",
});
console.log(result.hash);
ts
const result = await manager.signTransaction({
  txJson: {
    TransactionType: "Payment",
    Account: account.address,
    Destination: "<recipient_address>",
    Amount: "1000000",
  },
  maxFeeDrops: "50000",
});
console.log(result.txBlob); // Signed, not broadcast

Requests use xrpl_signTransaction. Sign-only must return a signed blob and must not broadcast. A wallet that cannot fulfill this contract cannot supply Kit's portable message-proof flow either.

NFT Transactions ​

Each tab signs and submits one transaction. Wallet display and supported transaction types depend on the wallet/provider; generic signing is not a promise of support for every amendment.

ts
await manager.signAndSubmit({
  txJson: {
    TransactionType: "NFTokenMint",
    Account: account.address,
    NFTokenTaxon: 0,
    Flags: 8, // tfTransferable
  },
  maxFeeDrops: "50000",
});
ts
await manager.signAndSubmit({
  txJson: {
    TransactionType: "NFTokenCreateOffer",
    Account: account.address,
    NFTokenID: "<nft_id>",
    Amount: "1000000",
    Flags: 1, // tfSellNFToken
  },
  maxFeeDrops: "50000",
});
ts
await manager.signAndSubmit({
  txJson: {
    TransactionType: "NFTokenAcceptOffer",
    Account: account.address, // Buyer's account
    NFTokenSellOffer: "<sell_offer_id>",
  },
  maxFeeDrops: "50000",
});
ts
await manager.signAndSubmit({
  txJson: {
    TransactionType: "NFTokenCancelOffer",
    Account: account.address, // Offer creator's account
    NFTokenOffers: ["<offer_id>"],
  },
  maxFeeDrops: "50000",
});
ts
await manager.signAndSubmit({
  txJson: {
    TransactionType: "NFTokenBurn",
    Account: account.address,
    NFTokenID: "<nft_id>",
  },
  maxFeeDrops: "50000",
});

Burning permanently destroys the NFT. For buy offers, brokered acceptance and additional fields, see NFT Marketplace. Xahau uses different transaction examples; see the Xahau guide.

For sign-only NFT requests, pass the same txJson to manager.signTransaction() when the connected wallet supports it.

Authentication ​

ts
const proof = await manager.signMessage({ message: "Verify wallet ownership" });
console.log(proof.signatureKind); // "signedTx"
console.log(proof.txBlob);

Kit's portable flow signs a 1-drop Payment with the message in a Memo, without submitting it. It returns a transaction proof, not a compact signature; see Message Authentication. Set signMessage: false to disable this capability. Native signIn() is not exposed; never broadcast the authentication transaction.

Sessions and Disconnect ​

manager.autoReconnect() can restore a generic WalletConnect entry from a still-valid stored SignClient session. Detail entries require an explicit connection; they do not background-restore after reload.

manager.disconnect() closes the active pairing/session and clears Kit state. After a request-time stale pairing/proposal error, reconnect explicitly; do not automatically replay a signing/submission request with an unknown outcome.

Integration Notes ​

modalModeDesktopMobile
"always"AppKitAppKit
"mobile-only"Custom QR eventAppKit
"never"Custom QR eventCustom QR event

For custom QR, set useModal: false, modalMode: "never" and handle onQr or manager qr events. The built-in Kit modal can render these events; custom UIs must render the returned URI themselves.

Wallet Detail Entries ​

ts
import { createWalletConnectAdapters } from "@xrpl-wallet-kit/adapter-walletconnect";

const adapters = createWalletConnectAdapters({
  projectId: "YOUR_WALLETCONNECT_PROJECT_ID",
  mode: "details", // "default" creates one generic entry
  wallets: ["bitget", "girin"], // or "all"
});
WalletDetail ID
Bitget Walletbitget
Joey Walletjoey
Girin Walletgirin
Bifrost Walletbifrost
StaticBitstaticbit

Joey's native extension is the separate Joey Wallet adapter, ID joey-wallet.

Session Methods ​

The adapter proposes xrpl_signTransaction, xrpl_signTransactionFor and xrpl_signMessage through optional namespaces. Approval of a session does not prove support for every optional method. Kit's signMessage() flow above still requires sign-only transaction support rather than assuming a raw native message signature.

Troubleshooting ​

SymptomAction
QR/URI expiresStart a fresh connection and approve it before expiry
Session does not restoreCheck expiry; detail-mode entries intentionally require reconnecting
Wrong networkConnect to the requested chain and select it in the wallet
Stale pairing/proposal/key errorReconnect after cleanup; check any dispatched transaction before retrying
Sign-only does not return a blobUse a wallet supporting the required sign-only contract

Released under the MIT License.