Skip to content

Vue 3 ​

@xrpl-commons/xrpl-connect-vue provides a Vue plugin, reactive composables, and a typed wrapper for the wallet connector modal. Configure the wallet manager once and consume the same state anywhere in the application.

Installation ​

bash
npm install @xrpl-commons/xrpl-connect-vue xrpl-connect xrpl@^4 vue

Configure the plugin ​

The install command selects the coordinated stable v1 packages. Keep the Vue binding and xrpl-connect on the same release line.

Import adapters from xrpl-connect in the browser entry point. Evaluating that package entry also registers the wallet connector custom element. Then install the Vue plugin before mounting the application:

ts
// main.ts
import { createApp } from 'vue';
import { CrossmarkAdapter, XamanAdapter } from 'xrpl-connect';
import { createXrplConnect } from '@xrpl-commons/xrpl-connect-vue';
import App from './App.vue';

const app = createApp(App);

app.use(
  createXrplConnect({
    adapters: [new XamanAdapter({ apiKey: 'YOUR_API_KEY' }), new CrossmarkAdapter()],
    network: 'testnet',
    autoConnect: true,
  })
);

app.mount('#app');

Each plugin installation owns one WalletManager. Its state and event listeners are isolated from other Vue applications on the same page and are released when the app unmounts.

Wallet state and modal ​

useWallet() returns readonly Vue refs, so use them directly in templates and through .value in scripts. useWalletModal() returns a readonly ready ref, open(): Promise<void>, openAndWait(): Promise<AccountInfo>, and close(): void for the active connector. open() resolves when the modal opens; wallet availability is discovered in the background with cached choices or a loading status. Await openAndWait() when the caller needs the connected account; it rejects if opening fails or the modal closes first.

All composables must run below an application that installed createXrplConnect(). ready becomes true after a connector registers and returns to false after the last connector unmounts. Calling open() or openAndWait() while it is false rejects with a namespaced setup error. If several connectors are mounted, the most recently registered connector owns modal calls; unmounting it falls back to the previous connector. Keep one mounted <WalletConnector> when that ownership rule is unnecessary.

For a headless flow, connect directly by adapter ID:

ts
const { connect } = useWallet();
await connect('crossmark');

With autoConnect: true, the plugin restores the persisted session on the client after its reactive listeners are ready.

vue
<script setup lang="ts">
import { WalletConnector, useWallet, useWalletModal } from '@xrpl-commons/xrpl-connect-vue';

const { connected, account, connecting, error, disconnect } = useWallet();
const { ready, open } = useWalletModal();
</script>

<template>
  <button v-if="!connected" :disabled="!ready || connecting" @click="open">
    {{ connecting ? 'Connecting…' : 'Connect wallet' }}
  </button>
  <button v-else @click="disconnect">Disconnect {{ account?.address }}</button>

  <p v-if="error">Error [{{ error.code }}]: {{ error.message }}</p>

  <WalletConnector
    primary-wallet="xaman"
    :wallets="['xaman', 'crossmark']"
    showUnavailable
    theme="dark"
    :css-vars="{ '--xc-primary-color': '#a78bfa' }"
    @connecting="(walletId) => console.log('Connecting', walletId)"
    @connect="(connectedAccount) => console.log('Connected', connectedAccount.address)"
    @error="(walletError) => console.error(walletError.code, walletError.message)"
  />
</template>

Signing ​

Signing actions are bound to the injected manager and reject with typed WalletError values.

For Xaman, the connection modal does not provide a signing dialog. Configure the adapter's onQRCode callback to present explicit signing-page and mobile deep-link actions when asynchronous popups are unsuitable. The Nuxt example shows the callback and cleanup lifecycle; in plain Vue, use an app-owned shared ref supplied through provide/inject instead of Nuxt's useState. Keep that state scoped to the app. OAuth login separately needs compatible popup headers.

vue
<script setup lang="ts">
import { ref } from 'vue';
import {
  isWalletError,
  useSigner,
  useWallet,
  WalletErrorCode,
} from '@xrpl-commons/xrpl-connect-vue';

const { account, connected } = useWallet();
const { signAndSubmit } = useSigner();
const submitting = ref(false);
const result = ref<string | null>(null);

async function sendPayment() {
  if (!connected.value || !account.value) return;
  submitting.value = true;

  try {
    const submitted = await signAndSubmit({
      TransactionType: 'Payment',
      Account: account.value.address,
      Destination: 'rN7n7otQDd6FczFgLdlqtyMVrn3HMfXoQT',
      Amount: '1000000',
    });
    result.value = submitted.hash;
  } catch (error) {
    if (isWalletError(error) && error.code === WalletErrorCode.SIGN_REJECTED) return;
    throw error;
  } finally {
    submitting.value = false;
  }
}
</script>

<template>
  <button :disabled="submitting || !connected" @click="sendPayment">Send payment</button>
  <p v-if="result">Submitted: {{ result }}</p>
</template>

API summary ​

  • createXrplConnect(config) installs an isolated wallet manager using core WalletManagerOptions.
  • useWallet() returns manager, connected, account, network, connecting, error, connect, and disconnect.
  • useSigner() returns sign, signAndSubmit, and signMessage.
  • useWalletModal() returns readonly ready, awaitable open and openAndWait, and close.
  • <WalletConnector> wraps the browser custom element with typed Vue props and events.

WalletConnector accepts primaryWallet, wallets, showUnavailable, theme, and cssVars, and emits connecting, connect, and typed error events. Unavailable wallets are hidden by default. Set the camelCase Vue prop showUnavailable to show an Install action when an adapter provides a download URL, or a disabled Unavailable row when it does not. Removing the prop or setting it to false removes the native show-unavailable attribute. Use manager.supports('signMessage') before showing optional signing actions.

SSR and Nuxt ​

The package itself is safe to import during server rendering. The connector is a browser custom element, so evaluate xrpl-connect, install the plugin, and invoke the injected composables only from client code. In Nuxt, a template <ClientOnly> does not prevent the same component's setup function from running during SSR; use a .client.vue consumer or a child wholly below the client-only boundary. See the Nuxt guide for the complete pattern.

Released under the MIT License.