WalletConnect Integration

The Openloop SDK supports remote device access over WalletConnect v2 in two ways.

The Two Approaches

Approach Level Description
WcTransport Low-level Relays APDU commands through the WalletConnect relay
AppKit High-level Standard multi-chain WC connection via Reown AppKit

WcTransport (APDU Relay)

WcTransport implements ITransport and sends APDU commands to a remote Openloop Connect app through the WalletConnect v2 relay.

How It Works

Diagram 0

Hex-encoded APDUs are sent and received over the custom JSON-RPC method openloop_exchange.

Setup

import { WcTransport, EthereumApp, DEFAULT_ETH_PATH } from '@openloop/sdk-core'
import SignClient from '@walletconnect/sign-client'

// Initialize the WalletConnect SignClient
const client = await SignClient.init({
  projectId: 'your-project-id',
})

// Pair and establish a session
const { uri, approval } = await client.connect({
  requiredNamespaces: {
    eip155: {
      methods: ['openloop_exchange', 'openloop_lock', 'openloop_unlock'],
      chains: ['eip155:1'],
      events: [],
    },
  },
})

// Show the URI as a QR code → the user scans it with Openloop Connect
console.log('Pairing URI:', uri)

// Wait for session approval
const session = await approval()

// Create the WcTransport
const transport = new WcTransport({
  client,
  session: { topic: session.topic },
  chainId: 'eip155:1', // optional (default: 'eip155:1')
})

await transport.open()

// The regular App classes work as-is
const eth = new EthereumApp(transport)
const { address } = await eth.getAddress(DEFAULT_ETH_PATH)

WcTransport Type Definitions

interface WcTransportOptions {
  client: IWcSignClient   // WalletConnect SignClient instance
  session: WcSession       // Active session { topic: string }
  chainId?: string         // Chain ID (default: "eip155:1")
}

interface IWcSignClient {
  request<T>(params: {
    topic: string
    chainId: string
    request: { method: string; params: unknown }
  }): Promise<T>
}

interface WcSession {
  topic: string
}

Supported Methods

Method Description
openloop_exchange Send and receive APDU commands
openloop_lock Acquire the exclusive device lock
openloop_unlock Release the exclusive device lock

Key Features


AppKit (High-Level WC)

With Reown AppKit you sign using WalletConnect’s standard methods — eth_signTransaction, personal_sign, and so on. This approach never handles APDUs directly; Openloop Connect drives the device internally.

Supported Chains and Methods

EVM (eip155)

Chains: - eip155:1 — Ethereum Mainnet - eip155:11155111 — Sepolia Testnet

Methods: | Method | Description | |———|——| | eth_sendTransaction | Send a transaction | | eth_signTransaction | Sign a transaction | | eth_sign | Sign data | | personal_sign | Sign an EIP-191 message | | eth_signTypedData | Sign EIP-712 typed data | | eth_signTypedData_v3 | EIP-712 v3 | | eth_signTypedData_v4 | EIP-712 v4 | | wallet_getCapabilities | Get the wallet’s capabilities |

Bitcoin (bip122)

Chains: - bip122:000000000019d6689c085ae165831e93 — Bitcoin Mainnet - bip122:000000000933ea01ad0ee984209779ba — Bitcoin Testnet3

Methods: | Method | Description | |———|——| | signPsbt | Sign a PSBT | | getAccountAddresses | Get the account addresses | | signMessage | Sign a message | | sendTransfer | Send a transfer |

Solana

Chains: - solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp — Mainnet Beta - solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 — Devnet

Methods: | Method | Description | |———|——| | solana_signTransaction | Sign a transaction | | solana_signAllTransactions | Sign multiple transactions | | solana_signAndSendTransaction | Sign and send | | solana_signMessage | Sign a message |

TRON

Chains: - tron:0x2b6653dc — TRON Mainnet - tron:0x94a9059e — TRON Shasta Testnet

Methods: | Method | Description | |———|——| | tron_signTransaction | Sign a transaction | | tron_signMessage | Sign a message |

AppKit Configuration Example

import { createAppKit } from '@reown/appkit/react'
import { WagmiAdapter } from '@reown/appkit-adapter-wagmi'
import { SolanaAdapter } from '@reown/appkit-adapter-solana'
import { BitcoinAdapter } from '@reown/appkit-adapter-bitcoin'
import { TronAdapter } from '@reown/appkit-adapter-tron'
import { mainnet, sepolia } from '@reown/appkit/networks'

const projectId = 'your-walletconnect-project-id'

// Create the adapters
const wagmiAdapter = new WagmiAdapter({ projectId, networks: [mainnet, sepolia] })
const solanaAdapter = new SolanaAdapter()
const bitcoinAdapter = new BitcoinAdapter()
const tronAdapter = new TronAdapter()

// Create the AppKit instance
const modal = createAppKit({
  projectId,
  adapters: [wagmiAdapter, solanaAdapter, bitcoinAdapter, tronAdapter],
  networks: [mainnet, sepolia],
  metadata: {
    name: 'My dApp',
    description: 'My dApp with Openloop',
    url: 'https://my-dapp.com',
    icons: ['https://my-dapp.com/icon.png'],
  },
  customWallets: [
    {
      id: 'openloop-connect',
      name: 'Openloop Connect',
      homepage: 'https://crypto.haudi.jp/openloop/',
      mobile_link: 'openloop://',
      desktop_link: 'openloop://',
      image_url: 'https://crypto.haudi.jp/openloop/images/logo/openloop-icon.png',
    },
  ],
})

Choosing Between WcTransport and AppKit

Criterion WcTransport AppKit
APDU-level control Full control Abstracted away
Ease of adoption Somewhat involved Easy
UI components None (build your own) Modal included
Multi-chain Manual switching Automatic switching
EIP-7702 Supported Not supported
Supported wallets Openloop Connect only Every WC-compatible wallet

Recommendation: - Integrating with the Openloop device is the main goal → WcTransport - You want to support multiple wallets → AppKit


Limitations

Next Steps