Skip to content

Wallet Integration

The SDK never talks to a wallet library directly. Instead, VaultProvider accepts a single bridge object — the WalletAdapter — that any wallet stack (wagmi, Privy, WalletConnect, a relayer) can implement.

The WalletAdapter interface

interface WalletAdapter {
  platform: "web" | "native";
  connect(): Promise<Address>;
  disconnect(): Promise<void>;
  getAddress(): Promise<Address | null>;
  sendTransaction(tx: TransactionRequest): Promise<string>; // returns tx hash
  isConnected(): boolean;
}

interface TransactionRequest {
  to: Address;
  data: `0x${string}`;
  value: bigint;
}

Built-in adapters

  • WebWalletAdapter — bridges to injected window.ethereum (MetaMask etc.). Uses eth_requestAccounts on connect(), eth_accounts on getAddress(), eth_sendTransaction for txs, and subscribes to accountsChanged. This is the default on web when no walletAdapter is passed.
  • RNWalletAdapter — deliberate stub for React Native; connect() and sendTransaction() throw "Pass a custom walletAdapter to VaultProvider for React Native."

Note

The injected-wallet default works, but most partners already have a wallet stack. The recommended default path is a custom adapter over that stack — see the wagmi example below.

The canonical adapter over wagmi:

import { useWalletClient, useAccount } from "wagmi";
import { VaultProvider, type WalletAdapter } from "@arkonix.xyz/arkonix-vault-sdk";

function WagmiVaultProvider({ children }: { children: React.ReactNode }) {
  const { data: walletClient } = useWalletClient();
  const { address } = useAccount();

  const walletAdapter: WalletAdapter = useMemo(() => ({
    platform: "web" as const,
    isConnected: () => !!address,
    getAddress: async () => address ?? null,
    connect: async () => { throw new Error("Use RainbowKit connect button"); },
    disconnect: async () => {},
    sendTransaction: async (tx) => {
      if (!walletClient) throw new Error("Wallet not connected");
      return walletClient.sendTransaction({ to: tx.to, data: tx.data, value: tx.value });
    },
  }), [walletClient, address]);

  return (
    <VaultProvider config={{ chainId: 42161, rpcUrl: "https://arb1.arbitrum.io/rpc" }}
                   walletAdapter={walletAdapter}>
      {children}
    </VaultProvider>
  );
}

Connection lifecycle stays with your existing wallet UI (here, RainbowKit); the adapter only reports the address and sends transactions.

React Native

React Native apps must pass a custom adapter — the built-in RNWalletAdapter is a stub that throws. The integration is identical in shape to the wagmi example, with platform: "native", bridging to WalletConnect / Privy / whatever wallet library the app already uses.

Platform utilities

Exported helpers for platform detection:

isReactNative(): boolean
isWeb(): boolean
getPlatform(): "web" | "native"

Detection is based on navigator.product === "ReactNative".