توفر حزمة @solana-commerce/connector اتصال محفظة بدون واجهة مرئية مبني على
معيار المحفظة. تدير اكتشاف
المحفظة، وحالة الاتصال، وإدارة الحسابات، وإعادة الاتصال التلقائي. الحزمة مصممة
لتكون مستقلة عن إطار العمل مع روابط React مضمنة. وهي مُصممة خصيصاً للاستخدام
السلس في Solana Commerce Kit ومتوافقة مع
@solana/kit و
gill.
اتصال المحفظة
التثبيت
pnpm add @solana-commerce/connector
تكوين المزود
ConnectorProvider
يقوم مكون ConnectorProvider بتغليف تطبيقك ويوفر حالة اتصال المحفظة لجميع
المكونات الفرعية. يدير نسخة واحدة من ConnectorClient تستمر عبر دورات
تركيب/إلغاء تركيب المكونات.
الخصائص
يتم تمرير جميع التكوينات عبر خاصية config:
config(ConnectorConfig، اختيارية) - كائن التكوين للموصل. جميع الحقول اختيارية.
ConnectorConfig
كائن التكوين لسلوك اتصال المحفظة.
الحقول الاختيارية
-
autoConnect(boolean) - عندما تكونtrue، يعيد الاتصال تلقائياً بآخر محفظة مستخدمة عند التركيب. يتم تخزين تفضيل المحفظة في وحدة التخزين المكونة (الافتراضي هوlocalStorage). الافتراضي:false. -
debug(boolean) - يتيح تسجيل وحدة التحكم المفصل لتصحيح أخطاء تدفقات الاتصال وتغييرات الحساب والأخطاء. تتضمن السجلات بادئات مثل[Connector]و[ConnectorProvider]. الافتراضي:false. -
accountPollingIntervalMs(number) - الفاصل الزمني للاستقصاء بالميلي ثانية للتحقق من تغييرات الحساب عندما لا تدعم المحفظة ميزةstandard:events. معظم المحافظ الحديثة تدعم الأحداث، لذا فإن الاستقصاء هو حل احتياطي. الافتراضي:1500(1.5 ثانية). -
storage(Storage) - محول تخزين مخصص للحفاظ على تفضيلات المحفظة. يجب أن ينفذ:getItem(key: string): string | nullsetItem(key: string, value: string): voidremoveItem(key: string): void
الافتراضي:
window.localStorageعند توفره (المتصفح فقط). استخدم هذا لـ React Native (AsyncStorage) أو التخزين المخصص الآمن لـ SSR.
بنية المزود
يستخدم المزود نمط المثيل الوحيد مع عد المراجع:
- تشترك عدة نسخ من
ConnectorProviderفي نفسConnectorClient - يتم إنشاء العميل عند أول تركيب ويستمر عبر حالات إلغاء التركيب
- عندما يتم إلغاء تركيب جميع المزودات، يتأخر التنظيف لمدة 5 ثوانٍ للتعامل مع عمليات إعادة التركيب السريعة
- أثناء التنظيف، يتم قطع اتصال المحفظة وإزالة جميع مستمعي الأحداث
يمنع هذا التصميم قطع اتصال المحفظة أثناء تغييرات المسار أو تحديثات المكونات.
الخطافات
useConnector()
الخطاف الأساسي للوصول إلى حالة اتصال المحفظة والإجراءات. يجب استخدامه داخل
ConnectorProvider.
يُرجع كائن ConnectorSnapshot يحتوي على:
خصائص الحالة
-
wallets(WalletInfo[]) - مصفوفة لجميع محافظ Wallet Standard المتوافقة المكتشفة. يتم التحديث تلقائياً عند تثبيت المحافظ أو إلغاء تثبيتها. تتضمن كل محفظة بيانات وصفية مثل الاسم والأيقونة والقدرات. راجع WalletInfo. -
selectedWallet(Wallet | null) - كائن محفظة Wallet Standard المتصلة حالياً.nullعند قطع الاتصال. هذا هو نسخة المحفظة الخام من واجهة برمجة تطبيقات Wallet Standard. -
connected(boolean) - حالة الاتصال.trueعندما تكون المحفظة متصلة والحسابات متاحة. استخدم هذا للعرض الشرطي لواجهة المستخدم. -
connecting(boolean) - حالة التحميل أثناء اتصال المحفظة.trueبين استدعاءselect()واستلام نتيجة الاتصال. استخدم هذا لإظهار مؤشرات التحميل أو تعطيل الأزرار. -
accounts(AccountInfo[]) - مصفوفة الحسابات من المحفظة المتصلة. توفر معظم المحافظ حساباً واحداً، لكن بعضها يدعم حسابات متعددة. يتم التحديث تلقائياً عبر أحداث المحفظة أو الاستطلاع. راجع AccountInfo. -
selectedAccount(string | null) - عنوان الحساب المحدد حالياً (المفتاح العام المشفر بنظام base58). عندما تتصل محفظة بحساب جديد، يتم تحديد ذلك الحساب تلقائياً. وإلا، يتم الاحتفاظ بالحساب المحدد مسبقاً.
طرق الإجراءات
-
select((walletName: string) => Promise<void>) - يتصل بمحفظة بالاسم (على سبيل المثال،"Phantom"،"Solflare"). يجب أن يطابق اسم المحفظة حقلnameللمحفظة المكتشفة تمامًا.العملية:
- تعيين
connecting: true - استدعاء ميزة
standard:connectالخاصة بالمحفظة - استرجاع الحسابات من المحفظة
- الاشتراك في أحداث المحفظة (أو بدء الاستطلاع إذا لم تكن الأحداث متاحة)
- حفظ تفضيل المحفظة في التخزين المهيأ
- تحديث الحالة بالحسابات والحساب المحدد
يطرح خطأ: إذا لم يتم العثور على المحفظة، أو لا تدعم المحفظة الاتصال، أو رفض المستخدم الاتصال.
- تعيين
-
disconnect(() => Promise<void>) - يقطع الاتصال بالمحفظة الحالية وينظف جميع الحالات.العملية:
- إلغاء الاشتراك في أحداث المحفظة
- إيقاف استطلاع الحسابات
- استدعاء ميزة
standard:disconnectالخاصة بالمحفظة إن كانت متاحة - مسح المحفظة المحددة والحسابات والحساب المحدد
- إزالة تفضيل المحفظة من التخزين
لا يطرح أخطاء أبدًا (يتم تسجيل الأخطاء إذا كان التصحيح مفعلاً).
-
selectAccount((address: string) => Promise<void>) - يبدل الحساب المحدد إلى عنوان مختلف من المحفظة المتصلة. إذا لم يكن العنوان موجودًا في مصفوفة الحسابات الحالية، يطلق إعادة اتصال لجلب الحسابات المحدثة.يطرح خطأ: إذا لم تكن هناك محفظة متصلة أو لم يتم العثور على الحساب المطلوب بعد إعادة الاتصال.
useConnectorClient()
يوفر وصولاً مباشرًا إلى مثيل ConnectorClient الأساسي لحالات الاستخدام
المتقدمة.
يُرجع: ConnectorClient | null - مثيل العميل الفردي، أو null عند
الاستخدام خارج ConnectorProvider.
حالات الاستخدام:
- الوصول المباشر إلى
getConnectorState()لقراءات الحالة الحتمية - الاشتراك اليدوي باستخدام
subscribe(listener)لمستمعي الحالة المخصصين - استدعاء
destroy()للتنظيف القسري (غير موصى به في الاستخدام العادي)
مثال:
const client = useConnectorClient();// Get current state without triggering re-renderconst state = client?.getConnectorState();// Subscribe to state changes manuallyuseEffect(() => {if (!client) return;const unsubscribe = client.subscribe((state) => {console.log("Wallet state changed:", state);});return unsubscribe;}, [client]);
تعريفات الأنواع
WalletInfo
بيانات تعريفية حول محفظة مكتشفة.
interface WalletInfo {wallet: Wallet; // Raw Wallet Standard wallet objectname: string; // Display name (e.g., "Phantom", "Solflare")icon?: string; // Data URL for wallet icon (base64 encoded)installed: boolean; // Always true (only installed wallets are discovered)connectable?: boolean; // Whether wallet supports required features}
متطلبات connectable: تكون المحفظة قابلة للاتصال عندما تدعم:
- ميزة
standard:connect - ميزة
standard:disconnect - سلاسل سولانا (يتم اكتشافها عبر
wallet.chainsالتي تحتوي على"solana")
تظهر المحافظ غير القابلة للاتصال في مصفوفة wallets لكن لا يمكن تحديدها.
AccountInfo
معلومات حول حساب المحفظة.
interface AccountInfo {address: string; // Base58-encoded public keyicon?: string; // Account-specific icon (data URL)raw: WalletAccount; // Raw WalletAccount object from Wallet Standard}
يوفر حقل raw الوصول إلى خصائص إضافية للحساب:
address: string- المفتاح العام المشفر بنظام Base58publicKey: Uint8Array- بايتات المفتاح العام الأوليةlabel?: string- تسمية الحساب (إذا وفرتها المحفظة)icon?: string- أيقونة خاصة بالحساب (رابط بيانات)chains: string[]- السلاسل المدعومة لهذا الحسابfeatures: string[]- الميزات المدعومة لهذا الحساب
ConnectorSnapshot
نوع الإرجاع لـ useConnector()، يجمع بين الحالة والإجراءات.
type ConnectorSnapshot = ConnectorState & {select: (walletName: string) => Promise<void>;disconnect: () => Promise<void>;selectAccount: (address: string) => Promise<void>;};interface ConnectorState {wallets: WalletInfo[];selectedWallet: Wallet | null;connected: boolean;connecting: boolean;accounts: AccountInfo[];selectedAccount: string | null;}
كشف تغيير الحساب
يكتشف الموصل تلقائياً عندما تتغير حسابات المحفظة (يضيف المستخدم حسابات أو يحذفها، أو يبدل بين الحسابات في المحفظة). يتم استخدام استراتيجيتين:
على أساس الأحداث (مفضل)
عندما تدعم المحفظة standard:events، يشترك الموصل في أحداث change:
- يستقبل إشعارات فورية عندما تتغير الحسابات
- أكثر كفاءة (بدون استطلاع دوري)
- يجمع الحسابات من كل من الحدث و
wallet.accountsللتعامل مع المحافظ التي تتضمن فقط الحساب المحدد في الأحداث
الاستطلاع الاحتياطي
عندما لا تكون الأحداث مدعومة، يستطلع الموصل wallet.accounts:
- يتحقق كل
accountPollingIntervalMs(افتراضياً: 1500 ميلي ثانية) - يقارن عناوين الحسابات لاكتشاف التغييرات
- يطلق إعادة العرض فقط عندما تتغير الحسابات فعلياً
منطق تحديد الحساب:
- عندما تتغير الحسابات، احتفظ بالحساب المحدد إذا كان لا يزال موجوداً
- إذا تمت إزالة الحساب المحدد، حدد أول حساب متاح
- عند الاتصال بحساب جديد (غير موجود في الحسابات السابقة)، فضل الحساب الجديد
التخزين والاتصال التلقائي
استمرارية التخزين
يقوم الموصل بتخزين مفتاح واحد في وحدة التخزين المُكوَّنة:
- المفتاح:
arc-connector:lastWallet - القيمة: اسم المحفظة (مثل
"Phantom")
عمليات التخزين محاطة بكتلة try-catch للتعامل مع:
- إطارات iframe المعزولة حيث يطرح
localStorageاستثناءً - بيئات SSR حيث يكون
windowغير معرّف - React Native حيث لا يوجد
localStorage
إذا فشل التخزين، يستمر الموصل بدون استمرارية (دون طرح أخطاء).
سلوك الاتصال التلقائي
عندما يكون autoConnect: true:
- عند التحميل، يقرأ اسم المحفظة الأخير من وحدة التخزين
- ينتظر 100 ميلي ثانية (للسماح للمحافظ بالتسجيل)
- يستدعي
select(walletName)إذا تم اكتشاف المحفظة - إذا فشل الاتصال التلقائي، يزيل التفضيل غير الصالح من وحدة التخزين
ملاحظة أمنية: التفضيل المُخزَّن هو مجرد اسم محفظة (نص)، وليس بيانات حساسة. تتعامل المحفظة مع المصادقة/الترخيص من خلال واجهتها الخاصة.
أمثلة الاستخدام
زر المحفظة الأساسي
import { ConnectorProvider, useConnector } from "@solana-commerce/connector";function App() {return (<ConnectorProvider config={{ autoConnect: true }}><WalletButton /></ConnectorProvider>);}function WalletButton() {const { wallets, select, disconnect, connected, accounts, connecting } =useConnector();if (!connected) {return (<div><h3>Connect Wallet</h3>{wallets.map((wallet) => (<buttonkey={wallet.name}onClick={() => select(wallet.name)}disabled={!wallet.connectable || connecting}>{wallet.icon && (<img src={wallet.icon} alt={wallet.name} width={24} />)}{wallet.name}{!wallet.connectable && " (Unsupported)"}</button>))}</div>);}return (<div><p>Connected: {accounts[0]?.address.slice(0, 8)}...</p><button onClick={disconnect}>Disconnect</button></div>);}
محدد الحسابات المتعددة
function AccountSelector() {const { accounts, selectedAccount, selectAccount } = useConnector();if (accounts.length <= 1) return null;return (<selectvalue={selectedAccount || ""}onChange={(e) => selectAccount(e.target.value)}>{accounts.map((account) => (<option key={account.address} value={account.address}>{account.raw.label || `${account.address.slice(0, 8)}...`}</option>))}</select>);}
مراقبة الاتصال
function ConnectionMonitor() {const { connected, selectedWallet, accounts } = useConnector();useEffect(() => {if (connected) {console.log("Wallet connected:", selectedWallet?.name);console.log("Accounts:",accounts.map((a) => a.address));}}, [connected, selectedWallet, accounts]);return null;}
المحافظ المدعومة
يدعم الموصل جميع المحافظ التي تطبق معيار المحفظة، بما في ذلك:
- Phantom
- Solflare
- Backpack
- Glow
- Brave Wallet
- Coinbase Wallet
- أي محفظة أخرى متوافقة مع معيار المحفظة
يتم اكتشاف المحافظ تلقائياً عندما تسجل نفسها في واجهة برمجة تطبيقات معيار المحفظة (لا حاجة لإعداد).
الاستخدام بدون واجهة (بدون React)
لتطبيقات غير React أو الاستخدام من جانب الخادم، استخدم ConnectorClient مباشرة:
import { ConnectorClient } from "@solana-commerce/connector";const connector = new ConnectorClient({autoConnect: true,debug: true});// Get current stateconst state = connector.getConnectorState();console.log("Available wallets:", state.wallets);// Connect to a walletawait connector.select("Phantom");// Subscribe to state changesconst unsubscribe = connector.subscribe((state) => {console.log("Connected:", state.connected);console.log("Accounts:", state.accounts);});// Switch accountawait connector.selectAccount("account-address-here");// Disconnectawait connector.disconnect();// Cleanup (removes all listeners and timers)connector.destroy();
ملاحظة: يدير ConnectorClient حالته الخاصة ولا يؤدي أبدًا إلى إعادة عرض
React. يجب عليك الاشتراك يدويًا في تغييرات الحالة.
Is this page helpful?