orderly-sdk-wallet-connection について
orderly-sdk-wallet-connection は、Orderly Network の DEX 開発者向けに、EVM・Solana ウォレットの設定、接続、アカウント状態管理を解説するガイドです。標準コネクターと Privy によるソーシャルログインの選択・設定も扱います。
主な機能
- 01EVM・Solana ウォレットの設定
- 02標準コネクターと Privy の選択肢
- 03接続状態とアカウント状態の管理
- 04対応チェーンの切り替えと制限
- 05ウォレット UI とアクセス制御
活用シーン
- 01新しい DEX のウォレット接続設定
- 02複数ウォレットとチェーン切り替えへの対応
- 03アカウント状態に応じた取引制御
- 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-wallets | MetaMask、Rabby、Coinbase など |
@web3-onboard/walletconnect | WalletConnect(モバイル/マルチプラットフォーム) |
@binance/w3w-blocknative-connector | Binance Web3 Wallet |
wagmi | EVM コネクター(injected、walletConnect) |
@solana/wallet-adapter-base | Solana アダプターの基盤とネットワーク列挙型 |
@solana/wallet-adapter-wallets | Phantom、Solflare、Ledger アダプター |
@solana-mobile/wallet-adapter-mobile | Solana 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 | ウォレット未接続のまま取引が有効 |
NotConnected | 0 | ウォレット未接続 |
Connected | 1 | ウォレット接続済み、Orderly アカウントなし |
NotSignedIn | 2 | アカウントは存在するが、サインインしていない |
SignedIn | 3 | Orderly にサインイン済み |
DisabledTrading | 4 | 取引が無効 |
EnableTrading | 5 | 取引が有効 |
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 |
|---|---|
| Arbitrum | 42161 |
| Optimism | 10 |
| Base | 8453 |
| Ethereum | 1 |
EVM テストネット
| チェーン | チェーン ID |
|---|---|
| Arbitrum Sepolia | 421614 |
| Base Sepolia | 84532 |
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を使用してください。ログイン方法のデフォルトは
ベストプラクティス
- WalletConnect のプロジェクト ID は設定から取得し、ハードコードしないでください。
networkIdは一度だけ導出し(例:getNetworkId())、ウォレットコネクターとOrderlyAppProviderの両方に渡します。- ネットワークの選択を
localStorage(orderly_network_id)に保存し、メインネットとテストネットを切り替える際に再読み込みします。 - Solana Mobile デバイスに対応する場合は、
SolanaMobileWalletAdapterを含めてください。 - Privy と標準コネクターのどちらを使うかは、ビルド時ではなく実行時に選択してください(Privy のアプリ ID が設定されているかどうかで判断します)。
関連スキル
- orderly-sdk-dex-architecture - プロバイダーの設定と構成
- orderly-sdk-install-dependency - ウォレットパッケージのインストール
- orderly-sdk-trading-workflows - 取引の実装
- orderly-sdk-debugging - ウォレットの問題のトラブルシューティング
- orderly-api-authentication - 認証フローの理解