mcpField
O
orderly-sdk-wallet-connection

orderly-sdk-wallet-connection

github.com/orderlynetwork開発247 回インストール3 日前に更新
リポジトリ

orderly-sdk-wallet-connection について

orderly-sdk-wallet-connection は、Orderly Network の DEX 開発者向けに、EVM・Solana ウォレットの設定、接続、アカウント状態管理を解説するガイドです。標準コネクターと Privy によるソーシャルログインの選択・設定も扱います。

主な機能

  1. 01EVM・Solana ウォレットの設定
  2. 02標準コネクターと Privy の選択肢
  3. 03接続状態とアカウント状態の管理
  4. 04対応チェーンの切り替えと制限
  5. 05ウォレット UI とアクセス制御

活用シーン

  1. 01新しい DEX のウォレット接続設定
  2. 02複数ウォレットとチェーン切り替えへの対応
  3. 03アカウント状態に応じた取引制御
  4. 04アプリへのソーシャルログイン追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/orderlynetwork/skills --skill orderly-sdk-wallet-connection

インストール後、Claude Code で/orderly-sdk-wallet-connectionを入力して読み込まれたか確認します。

詳細

Orderly Network:SDK ウォレット接続

Orderly Network の DEX アプリケーションでウォレット接続を統合するための包括的なガイドです。EVM(Ethereum、Arbitrum、Optimism、Base など)と Solana のウォレットに対応し、Privy(ソーシャルログイン)を使う方法も選択できます。

使用する場面

  • 新しい DEX でウォレット接続を設定する場合
  • 複数のウォレットタイプ(MetaMask、Phantom など)に対応する場合
  • チェーン切り替えを実装する場合
  • 標準コネクターと Privy のどちらを使うか選ぶ場合

前提条件

  • Orderly SDK パッケージがインストールされていること(orderly-sdk-install-dependency を参照)
  • プロバイダーが設定されていること(orderly-sdk-dex-architecture を参照)
  • ウォレットパッケージがインストールされていること

概要

Orderly Network はオムニチェーン取引に対応しており、ユーザーは複数のエコシステムのウォレットを接続できます。

  • EVM チェーン:Arbitrum、Optimism、Base、Ethereum、BSC など
  • Solana:Mainnet と Devnet

SDK には2 つのコネクターパッケージが用意されています。いずれかを選んでください。

パッケージ使用する場面
@orderly.network/wallet-connectorデフォルト — Web3-Onboard(EVM)+ Solana ウォレットアダプター
@orderly.network/wallet-connector-privyソーシャルログイン(Google、X、メール、パスキー)/埋め込みウォレットを使う場合

プロバイダーは実行時に選択されます。Privy アプリ ID が設定されている場合は Privy コネクターが使われ、設定されていない場合は標準コネクターが使われます。

evmInitial と solanaInitial はどちらも設定済みのプロパティです。これらにはウォレットのネットワークとウォレット一覧が含まれます。実際の DEX でこれらを省略することはありません。リファレンステンプレートでは常に両方を渡し、設定フラグを使って片方を個別に無効にできます。

必須の依存関係

# Connector package
npm install @orderly.network/wallet-connector

# EVM wallets
npm install @web3-onboard/injected-wallets @web3-onboard/walletconnect \
            @binance/w3w-blocknative-connector wagmi

# Solana wallets
npm install @solana/wallet-adapter-base @solana/wallet-adapter-wallets \
            @solana-mobile/wallet-adapter-mobile
パッケージ用途
@web3-onboard/injected-walletsMetaMask、Rabby、Coinbase など
@web3-onboard/walletconnectWalletConnect(モバイル/マルチプラットフォーム)
@binance/w3w-blocknative-connectorBinance Web3 Wallet
wagmiEVM コネクター(injected、walletConnect)
@solana/wallet-adapter-baseSolana アダプターの基盤とネットワーク列挙型
@solana/wallet-adapter-walletsPhantom、Solflare、Ledger アダプター
@solana-mobile/wallet-adapter-mobileSolana Mobile Wallet Adapter

標準コネクター

1. ウォレットコネクタープロバイダー

OrderlyAppProvider を WalletConnectorProvider でラップし、両方の初期設定を渡します。

// app/components/orderlyProvider/walletConnector.tsx
import { ReactNode } from 'react';
import { WalletConnectorProvider } from '@orderly.network/wallet-connector';
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
import type { NetworkId } from '@orderly.network/types';
import { getEvmInitialConfig, getSolanaWallets } from '@/utils/walletConfig';

const WalletConnector = ({
  children,
  networkId,
  disableEvm,
  disableSolana,
  projectId,
  appName,
}: {
  children: ReactNode;
  networkId: NetworkId;
  disableEvm?: boolean; // from your config
  disableSolana?: boolean; // from your config
  projectId?: string; // WalletConnect project id (see below)
  appName?: string;
}) => (
  <WalletConnectorProvider
    evmInitial={disableEvm ? undefined : getEvmInitialConfig(projectId, appName)}
    solanaInitial={
      disableSolana
        ? undefined
        : {
            network:
              networkId === 'mainnet' ? WalletAdapterNetwork.Mainnet : WalletAdapterNetwork.Devnet,
            wallets: getSolanaWallets(networkId),
          }
    }
  >
    {children}
  </WalletConnectorProvider>
);

export default WalletConnector;

networkId は、WalletConnectorProvider(Solana ネットワーク)と OrderlyAppProvider の間で一貫している必要があります。リファレンスプロバイダーでは、両方とも同じ getNetworkId() から取得しています。

2. EVM ウォレットの設定

テンプレートでは、EVM コネクターを2 つの層で構築します。getEvmConnectors()(Privy の方法で使われる wagmi の CreateConnectorFn[])と、getOnboardEvmWallets()(標準コネクター用の getEvmInitialConfig() で使われる Web3-Onboard モジュール)です。

// app/utils/walletConfig.ts (excerpt)
import { CreateConnectorFn } from 'wagmi';
import { injected, walletConnect } from 'wagmi/connectors';
import injectedOnboard from '@web3-onboard/injected-wallets';
import walletConnectOnboard from '@web3-onboard/walletconnect';
import binanceWallet from '@binance/w3w-blocknative-connector';

// wagmi connectors (Privy path)
export const getEvmConnectors = (
  projectId?: string,
  appName = 'Orderly App'
): CreateConnectorFn[] => {
  const connectors: CreateConnectorFn[] = [injected()];
  if (projectId && typeof window !== 'undefined') {
    connectors.push(
      walletConnect({
        projectId,
        showQrModal: true,
        metadata: {
          name: appName,
          description: appName,
          url: window.location.origin,
          icons: [`${window.location.origin}/favicon.webp`],
        },
      })
    );
  }
  return connectors;
};

// Web3-Onboard modules (standard connector path)
export const getOnboardEvmWallets = (projectId?: string) => {
  if (!projectId || typeof window === 'undefined') return [];
  return [
    injectedOnboard(),
    binanceWallet({ options: { lng: 'en' } }),
    walletConnectOnboard({
      projectId,
      qrModalOptions: { themeMode: 'dark' },
      dappUrl: window.location.origin,
    }),
  ];
};

// evmInitial shape: { options: { wallets, appMetadata } } — undefined if no projectId
export const getEvmInitialConfig = (projectId?: string, appName = 'Orderly App') => {
  const wallets = getOnboardEvmWallets(projectId);
  return wallets.length > 0
    ? { options: { wallets, appMetadata: { name: appName, description: appName } } }
    : undefined;
};

WalletConnect のプロジェクト IDは、アプリに合った方法で取得してください(リファレンステンプレートでは .env から import.meta.env.VITE_WALLETCONNECT_PROJECT_ID として読み取ります)。https://cloud.walletconnect.com で取得できます。プロジェクト ID がない場合、接続できるのは注入型のブラウザーウォレットのみです。

3. Solana ウォレットの設定
// app/utils/walletConfig.ts (excerpt)
import {
  WalletAdapterNetwork,
  WalletError,
  WalletNotReadyError,
  Adapter,
} from '@solana/wallet-adapter-base';
import {
  LedgerWalletAdapter,
  PhantomWalletAdapter,
  SolflareWalletAdapter,
} from '@solana/wallet-adapter-wallets';
import {
  createDefaultAddressSelector,
  createDefaultAuthorizationResultCache,
  SolanaMobileWalletAdapter,
} from '@solana-mobile/wallet-adapter-mobile';
import type { NetworkId } from '@orderly.network/types';

export const getSolanaWallets = (networkId: NetworkId) => {
  if (typeof window === 'undefined') return [];
  return [
    new PhantomWalletAdapter(),
    new SolflareWalletAdapter(),
    new LedgerWalletAdapter(),
    new SolanaMobileWalletAdapter({
      addressSelector: createDefaultAddressSelector(),
      appIdentity: { uri: `${location.protocol}//${location.host}` },
      authorizationResultCache: createDefaultAuthorizationResultCache(),
      chain: networkId === 'mainnet' ? WalletAdapterNetwork.Mainnet : WalletAdapterNetwork.Devnet,
      onWalletNotFound: () => Promise.reject(new WalletNotReadyError('wallet not ready')),
    }),
  ];
};

export const getSolanaConfig = (networkId: NetworkId) => ({
  wallets: getSolanaWallets(networkId),
  onError: (error: WalletError, adapter?: Adapter) => {
    console.log(error, adapter);
  },
});

Solana Mobile/Saga デバイスをサポートするには、SolanaMobileWalletAdapter(@solana-mobile/wallet-adapter-mobile から)が必要です。これを省略すると、モバイルの Solana ユーザーは接続できません。

ウォレットの状態へのアクセス

useWalletConnector() フックを使います。戻り値はフラットな構造で、connect、disconnect、setChain などはトップレベルにあります。wallet の下にネストされているわけではありません。

import { useWalletConnector } from '@orderly.network/hooks';

function WalletStatus() {
  const {
    connect, // (options?) => Promise<WalletState[]>
    disconnect, // (options)  => Promise<any[]>
    connecting, // boolean — connection in progress
    wallet, // WalletState | null
    connectedChain, // ConnectedChain | null
    setChain, // ({ chainId }) => Promise<any>
    chains, // available chains
    settingChain, // boolean
    namespace, // "evm" | "solana" | null
  } = useWalletConnector();

  return (
    <div>
      {wallet ? (
        <>
          <p>Connected: {wallet.accounts[0].address}</p>
          <p>Chain: {connectedChain?.id}</p>
          <button onClick={() => disconnect({})}>Disconnect</button>
        </>
      ) : (
        <button disabled={connecting} onClick={() => connect({ chainId: 42161 })}>
          {connecting ? 'Connecting…' : 'Connect Wallet'}
        </button>
      )}
    </div>
  );
}
チェーンを切り替える
const { setChain } = useWalletConnector();
await setChain({ chainId: 10 }); // Optimism
await setChain({ chainId: 8453 }); // Base

アカウントの状態遷移

ウォレット接続後、ユーザーは Orderly アカウントの設定(アカウントキーの作成、取引の有効化)を完了する必要があります。useAccount() を使って状態を追跡します。state.status は AccountStatusEnum です。

NotConnected(0) → Connected(1) → NotSignedIn(2) → SignedIn(3) → EnableTrading(5)
                                     │
                                     └→ DisabledTrading(4)
EnableTradingWithoutConnected(-1) — trading enabled without an explicit wallet
ステータス(AccountStatusEnum)値意味
EnableTradingWithoutConnected-1ウォレット未接続のまま取引が有効
NotConnected0ウォレット未接続
Connected1ウォレット接続済み、Orderly アカウントなし
NotSignedIn2アカウントは存在するが、サインインしていない
SignedIn3Orderly にサインイン済み
DisabledTrading4取引が無効
EnableTrading5取引が有効

AccountStatusEnum は @orderly.network/hooks ではなく、@orderly.network/types からエクスポートされています。

import { useAccount } from '@orderly.network/hooks';
import { AccountStatusEnum } from '@orderly.network/types';

function AccountStatus() {
  const { account, state, createOrderlyKey, createAccount } = useAccount();

  switch (state.status) {
    case AccountStatusEnum.NotConnected:
      return <ConnectWalletButton />;
    case AccountStatusEnum.Connected:
      return <button onClick={() => createAccount()}>Create Orderly Account</button>;
    case AccountStatusEnum.NotSignedIn:
      return <button onClick={() => createOrderlyKey()}>Enable Trading</button>;
    case AccountStatusEnum.SignedIn:
    case AccountStatusEnum.EnableTrading:
      return <TradingInterface />;
  }
}

ウォレット接続用 UI コンポーネント

接続ボタン/モーダル

SDK では、通知/モーダルシステムを通じて接続モーダルを利用できます。

import { modal } from '@orderly.network/ui';
import { WalletConnectorModalId } from '@orderly.network/ui-connector';

function ConnectButton() {
  return <button onClick={() => modal.show(WalletConnectorModalId)}>Connect Wallet</button>;
}

スタイル設定済みのボタンも、@orderly.network/ui-connector の ConnectWalletButton として利用できます。

AuthGuard

認証済みで、取引が有効なアカウントを必要とするコンテンツをラップします。

import { AuthGuard } from '@orderly.network/ui-connector';

function ProtectedArea() {
  return (
    <AuthGuard fallback={<ConnectPrompt />}>
      <TradingUI />
    </AuthGuard>
  );
}

対応チェーン

EVM メインネット
チェーンチェーン ID
Arbitrum42161
Optimism10
Base8453
Ethereum1
EVM テストネット
チェーンチェーン ID
Arbitrum Sepolia421614
Base Sepolia84532
Solana
ネットワーク内部 ID
メインネット1399811149
Devnet(devnet)

チェーンのフィルタリング

ユーザーが切り替えられるチェーンを制限します。chainFilter はネットワークをキーとし、各値は { id } の配列です。

<OrderlyAppProvider
  brokerId="your_broker_id"
  networkId="mainnet"
  chainFilter={{
    mainnet: [{ id: 42161 }, { id: 10 }],
    testnet: [{ id: 421614 }],
  }}
  defaultChain={{ mainnet: { id: 42161 } }}
>

リファレンステンプレートでは、これは VITE_ORDERLY_MAINNET_CHAINS / VITE_ORDERLY_TESTNET_CHAINS / VITE_DEFAULT_CHAIN から構成されます(orderly-sdk-dex-architecture を参照)。

チェーン変更の処理

ユーザーがメインネットチェーンとテストネットチェーンを切り替えた場合、networkId を切り替えて再読み込みし、SDK を正しい環境に再バインドする必要があります。

<OrderlyAppProvider
  brokerId="your_broker_id"
  networkId={networkId}
  onChainChanged={(_chainId, { isTestnet }) => {
    const current = getNetworkId();
    if ((isTestnet && current === 'mainnet') ||
        (!isTestnet && current === 'testnet')) {
      localStorage.setItem('orderly_network_id', isTestnet ? 'testnet' : 'mainnet');
      setTimeout(() => window.location.reload(), 100);
    }
  }}
>

Privy との統合(ソーシャルログイン)

Privy コネクターと Privy SDK(以前の @privy-io/react-auth ではなく、@privy-io/cross-app-connect)をインストールします。

npm install @orderly.network/wallet-connector-privy @privy-io/cross-app-connect

Privy プロバイダーは WalletConnectorPrivyProvider(WalletConnectorPrivy ではありません)です。network、termsOfUse、wagmiConfig、solanaConfig、privyConfig、および省略可能な abstractConfig を受け取ります。

// app/components/orderlyProvider/privyConnector.tsx
import { ReactNode } from 'react';
import { WalletConnectorPrivyProvider, Network } from '@orderly.network/wallet-connector-privy';
import { QueryClient } from '@tanstack/query-core';
import type { NetworkId } from '@orderly.network/types';
import { getEvmConnectors, getSolanaConfig } from '@/utils/walletConfig';

type LoginMethod = 'email' | 'passkey' | 'twitter' | 'google';

type PrivyConnectorProps = {
  children: ReactNode;
  networkId: NetworkId;
  appId: string;                                  // your Privy app id (required)
  loginMethods?: LoginMethod[];                   // default ['email']
  termsOfUse?: string;
  disableEvm?: boolean;
  disableSolana?: boolean;
  enableAbstract?: boolean;
  // plus projectId / appName if you enable EVM (see getEvmConnectors)
};

const PrivyConnector = ({
  children, networkId, appId,
  loginMethods = ['email'], termsOfUse,
  disableEvm, disableSolana, enableAbstract,
}: PrivyConnectorProps) => (
  <WalletConnectorPrivyProvider
    network={networkId === 'mainnet' ? Network.mainnet : Network.testnet}
    termsOfUse={termsOfUse}
    wagmiConfig={disableEvm ? undefined : { connectors: getEvmConnectors(/* projectId */, /* appName */) }}
    solanaConfig={disableSolana ? undefined : getSolanaConfig(networkId)}
    privyConfig={{
      config: { appearance: { showWalletLoginFirst: false }, loginMethods },
      appid: appId,
    }}
    abstractConfig={enableAbstract ? { queryClient: new QueryClient() } : undefined}
  >
    {children}
  </WalletConnectorPrivyProvider>
);

export default PrivyConnector;

プロバイダーの props(appId、loginMethods など)は設定から取得します。リファレンステンプレートでは .env(VITE_PRIVY_APP_ID、VITE_PRIVY_LOGIN_METHODS、…)を参照します。Privy のアプリ ID が設定されていない場合は、標準の WalletConnector を使用してください。ログイン方法のデフォルトは email です。

ベストプラクティス

  1. WalletConnect のプロジェクト ID は設定から取得し、ハードコードしないでください。
  2. networkId は一度だけ導出し(例:getNetworkId())、ウォレットコネクターと OrderlyAppProvider の両方に渡します。
  3. ネットワークの選択を localStorage(orderly_network_id)に保存し、メインネットとテストネットを切り替える際に再読み込みします。
  4. Solana Mobile デバイスに対応する場合は、SolanaMobileWalletAdapter を含めてください。
  5. Privy と標準コネクターのどちらを使うかは、ビルド時ではなく実行時に選択してください(Privy のアプリ ID が設定されているかどうかで判断します)。

関連スキル

  • orderly-sdk-dex-architecture - プロバイダーの設定と構成
  • orderly-sdk-install-dependency - ウォレットパッケージのインストール
  • orderly-sdk-trading-workflows - 取引の実装
  • orderly-sdk-debugging - ウォレットの問題のトラブルシューティング
  • orderly-api-authentication - 認証フローの理解

コメント