Το πακέτο @solana-commerce/connector παρέχει σύνδεση πορτοφολιού χωρίς UI
βασισμένη στο
Wallet Standard.
Διαχειρίζεται την ανακάλυψη πορτοφολιών, την κατάσταση σύνδεσης, τη διαχείριση
λογαριασμών και την αυτόματη επανασύνδεση. Το πακέτο είναι σχεδιασμένο να είναι
ανεξάρτητο από framework με ενσωματωμένες συνδέσεις React. Είναι προσαρμοσμένο
για απρόσκοπτη χρήση στο Solana Commerce Kit και είναι συμβατό με το
@solana/kit και το
gill.
Σύνδεση Πορτοφολιού
Εγκατάσταση
pnpm add @solana-commerce/connector
Διαμόρφωση Provider
ConnectorProvider
Το component ConnectorProvider περιτυλίγει την εφαρμογή σας και παρέχει την
κατάσταση σύνδεσης πορτοφολιού σε όλα τα θυγατρικά components. Διαχειρίζεται μια
singleton παρουσία ConnectorClient που διατηρείται σε όλους τους κύκλους
mount/unmount των components.
Props
Όλες οι ρυθμίσεις περνούν μέσω του prop config:
config(ConnectorConfig, προαιρετικό) - Αντικείμενο διαμόρφωσης για τον connector. Όλα τα πεδία είναι προαιρετικά.
ConnectorConfig
Αντικείμενο διαμόρφωσης για τη συμπεριφορά σύνδεσης πορτοφολιού.
Προαιρετικά Πεδία
-
autoConnect(boolean) - Όταν είναιtrue, επανασυνδέεται αυτόματα στο τελευταίο χρησιμοποιημένο πορτοφόλι κατά το mount. Η προτίμηση πορτοφολιού αποθηκεύεται στον διαμορφωμένο χώρο αποθήκευσης (προεπιλογήlocalStorage). Προεπιλογή:false. -
debug(boolean) - Ενεργοποιεί αναλυτική καταγραφή στην κονσόλα για debugging ροών σύνδεσης, αλλαγών λογαριασμού και σφαλμάτων. Τα logs περιλαμβάνουν προθέματα όπως[Connector]και[ConnectorProvider]. Προεπιλογή:false. -
accountPollingIntervalMs(number) - Διάστημα polling σε χιλιοστά του δευτερολέπτου για τον έλεγχο αλλαγών λογαριασμού όταν το πορτοφόλι δεν υποστηρίζει τη λειτουργίαstandard:events. Τα περισσότερα σύγχρονα πορτοφόλια υποστηρίζουν events, οπότε το polling είναι εφεδρική λύση. Προεπιλογή:1500(1,5 δευτερόλεπτα). -
storage(Storage) - Προσαρμοσμένος adapter αποθήκευσης για τη διατήρηση προτιμήσεων πορτοφολιού. Πρέπει να υλοποιεί:getItem(key: string): string | nullsetItem(key: string, value: string): voidremoveItem(key: string): void
Προεπιλογή:
window.localStorageόταν είναι διαθέσιμο (μόνο για browser). Χρησιμοποιήστε αυτό για React Native (AsyncStorage) ή προσαρμοσμένη SSR-safe αποθήκευση.
Αρχιτεκτονική Παρόχου
Ο πάροχος χρησιμοποιεί ένα μοτίβο singleton με μέτρηση αναφορών:
- Πολλαπλά στιγμιότυπα
ConnectorProviderμοιράζονται το ίδιοConnectorClient - Ο client δημιουργείται στην πρώτη προσάρτηση και παραμένει μετά την αποπροσάρτηση
- Όταν όλοι οι πάροχοι αποπροσαρτηθούν, η εκκαθάριση καθυστερεί κατά 5 δευτερόλεπτα για να χειριστεί γρήγορες επαναπροσαρτήσεις
- Κατά την εκκαθάριση, το πορτοφόλι αποσυνδέεται και όλοι οι event listeners αφαιρούνται
Αυτός ο σχεδιασμός αποτρέπει την αποσύνδεση του πορτοφολιού κατά τις αλλαγές διαδρομής ή τις ενημερώσεις στοιχείων.
Hooks
useConnector()
Το κύριο hook για πρόσβαση στην κατάσταση και τις ενέργειες σύνδεσης
πορτοφολιού. Πρέπει να χρησιμοποιείται εντός ενός ConnectorProvider.
Επιστρέφει ένα αντικείμενο ConnectorSnapshot που περιέχει:
Ιδιότητες Κατάστασης
-
wallets(WalletInfo[]) - Πίνακας όλων των ανιχνευμένων πορτοφολιών συμβατών με το Wallet Standard. Ενημερώνεται αυτόματα όταν εγκαθίστανται ή απεγκαθίστανται πορτοφόλια. Κάθε πορτοφόλι περιλαμβάνει μεταδεδομένα όπως όνομα, εικονίδιο και δυνατότητες. Δείτε WalletInfo. -
selectedWallet(Wallet | null) - Το τρέχον συνδεδεμένο αντικείμενο πορτοφολιού Wallet Standard.nullόταν είναι αποσυνδεδεμένο. Αυτό είναι το ακατέργαστο στιγμιότυπο πορτοφολιού από το Wallet Standard API. -
connected(boolean) - Κατάσταση σύνδεσης.trueόταν ένα πορτοφόλι είναι συνδεδεμένο και οι λογαριασμοί είναι διαθέσιμοι. Χρησιμοποιήστε το για υπό συνθήκη απόδοση UI. -
connecting(boolean) - Κατάσταση φόρτωσης κατά τη σύνδεση πορτοφολιού.trueμεταξύ της κλήσης τουselect()και της λήψης του αποτελέσματος σύνδεσης. Χρησιμοποιήστε το για να εμφανίσετε ενδείξεις φόρτωσης ή να απενεργοποιήσετε κουμπιά. -
accounts(AccountInfo[]) - Πίνακας λογαριασμών από το συνδεδεμένο πορτοφόλι. Τα περισσότερα πορτοφόλια παρέχουν έναν λογαριασμό, αλλά ορισμένα υποστηρίζουν πολλαπλούς. Ενημερώνεται αυτόματα μέσω συμβάντων πορτοφολιού ή polling. Δείτε AccountInfo. -
selectedAccount(string | null) - Η διεύθυνση του τρέχοντος επιλεγμένου λογαριασμού (δημόσιο κλειδί κωδικοποιημένο σε base58). Όταν ένα πορτοφόλι συνδέεται με έναν νέο λογαριασμό, αυτός ο λογαριασμός επιλέγεται αυτόματα. Διαφορετικά, ο προηγουμένως επιλεγμένος λογαριασμός διατηρείται.
Μέθοδοι Ενέργειας
-
select((walletName: string) => Promise<void>) - Συνδέεται σε ένα πορτοφόλι με βάση το όνομα (π.χ.,"Phantom","Solflare"). Το όνομα του πορτοφολιού πρέπει να ταιριάζει ακριβώς με το πεδίοnameενός ανακαλυφθέντος πορτοφολιού.Διαδικασία:
- Ορίζει το
connecting: true - Καλεί τη λειτουργία
standard:connectτου πορτοφολιού - Ανακτά τους λογαριασμούς από το πορτοφόλι
- Εγγράφεται στα συμβάντα του πορτοφολιού (ή ξεκινά polling αν τα συμβάντα δεν είναι διαθέσιμα)
- Αποθηκεύει την προτίμηση πορτοφολιού στον διαμορφωμένο αποθηκευτικό χώρο
- Ενημερώνει την κατάσταση με τους λογαριασμούς και τον επιλεγμένο λογαριασμό
Προκαλεί σφάλμα: Εάν το πορτοφόλι δεν βρεθεί, δεν υποστηρίζει σύνδεση ή η σύνδεση απορριφθεί από τον χρήστη.
- Ορίζει το
-
disconnect(() => Promise<void>) - Αποσυνδέει το τρέχον πορτοφόλι και καθαρίζει όλη την κατάσταση.Διαδικασία:
- Διαγράφεται από τα συμβάντα του πορτοφολιού
- Σταματά το polling λογαριασμών
- Καλεί τη λειτουργία
standard:disconnectτου πορτοφολιού αν είναι διαθέσιμη - Καθαρίζει το επιλεγμένο πορτοφόλι, τους λογαριασμούς και τον επιλεγμένο λογαριασμό
- Αφαιρεί την προτίμηση πορτοφολιού από τον αποθηκευτικό χώρο
Δεν προκαλεί ποτέ σφάλμα (τα σφάλματα καταγράφονται αν είναι ενεργοποιημένο το debug).
-
selectAccount((address: string) => Promise<void>) - Αλλάζει τον επιλεγμένο λογαριασμό σε διαφορετική διεύθυνση από το συνδεδεμένο πορτοφόλι. Εάν η διεύθυνση δεν υπάρχει στον τρέχοντα πίνακα λογαριασμών, ενεργοποιεί επανασύνδεση για ανάκτηση ενημερωμένων λογαριασμών.Προκαλεί σφάλμα: Εάν δεν υπάρχει συνδεδεμένο πορτοφόλι ή ο ζητούμενος λογαριασμός δεν βρεθεί μετά από επανασύνδεση.
useConnectorClient()
Παρέχει άμεση πρόσβαση στην υποκείμενη εμφάνιση ConnectorClient για
προχωρημένες περιπτώσεις χρήσης.
Επιστρέφει: ConnectorClient | null - Η μοναδική εμφάνιση client, ή 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 - Αλυσίδες Solana (ανιχνεύονται μέσω
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- Ακατέργαστα bytes δημόσιου κλειδιούlabel?: string- Ετικέτα λογαριασμού (εάν το πορτοφόλι την παρέχει)icon?: string- Εικονίδιο συγκεκριμένου λογαριασμού (data URL)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:
- Λαμβάνει ειδοποιήσεις σε πραγματικό χρόνο όταν αλλάζουν οι λογαριασμοί
- Πιο αποδοτική (χωρίς polling)
- Συγκεντρώνει λογαριασμούς τόσο από το συμβάν όσο και από το
wallet.accountsγια να χειριστεί πορτοφόλια που περιλαμβάνουν μόνο τον επιλεγμένο λογαριασμό στα συμβάντα
Εναλλακτική Λύση Polling
Όταν δεν υποστηρίζονται συμβάντα, ο συνδετήρας εκτελεί polling στο
wallet.accounts:
- Ελέγχει κάθε
accountPollingIntervalMs(προεπιλογή: 1500ms) - Συγκρίνει τις διευθύνσεις λογαριασμών για να ανιχνεύσει αλλαγές
- Ενεργοποιεί επανα-απόδοση μόνο όταν οι λογαριασμοί πραγματικά αλλάζουν
Λογική Επιλογής Λογαριασμού:
- Όταν αλλάζουν οι λογαριασμοί, διατηρείται ο επιλεγμένος λογαριασμός εάν εξακολουθεί να υπάρχει
- Εάν ο επιλεγμένος λογαριασμός αφαιρέθηκε, επιλέγεται ο πρώτος διαθέσιμος λογαριασμός
- Κατά τη σύνδεση με νέο λογαριασμό (που δεν υπάρχει στους προηγούμενους λογαριασμούς), προτιμάται ο νέος λογαριασμός
Αποθήκευση & Αυτόματη Σύνδεση
Μονιμότητα Αποθήκευσης
Ο σύνδεσμος αποθηκεύει ένα κλειδί στη ρυθμισμένη αποθήκευση:
- Κλειδί:
arc-connector:lastWallet - Τιμή: Όνομα πορτοφολιού (π.χ.,
"Phantom")
Οι λειτουργίες αποθήκευσης είναι τυλιγμένες σε try-catch για τη διαχείριση:
- Περιορισμένα iframes όπου το
localStorageπροκαλεί σφάλμα - Περιβάλλοντα SSR όπου το
windowδεν είναι ορισμένο - React Native όπου το
localStorageδεν υπάρχει
Εάν η αποθήκευση αποτύχει, ο σύνδεσμος συνεχίζει χωρίς μονιμότητα (δεν προκαλούνται σφάλματα).
Συμπεριφορά Αυτόματης Σύνδεσης
Όταν autoConnect: true:
- Κατά την προσάρτηση, διαβάζει το όνομα του τελευταίου πορτοφολιού από την αποθήκευση
- Περιμένει 100ms (επιτρέπει στα πορτοφόλια να εγγραφούν)
- Καλεί το
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;}
Υποστηριζόμενα Πορτοφόλια
Ο σύνδεσμος υποστηρίζει όλα τα πορτοφόλια που υλοποιούν το Wallet Standard, συμπεριλαμβανομένων:
- Phantom
- Solflare
- Backpack
- Glow
- Brave Wallet
- Coinbase Wallet
- Οποιοδήποτε άλλο πορτοφόλι συμβατό με το Wallet Standard
Τα πορτοφόλια ανακαλύπτονται αυτόματα όταν εγγράφονται στο Wallet Standard API (δεν απαιτείται διαμόρφωση).
Χρήση χωρίς UI (Χωρίς 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 διαχειρίζεται τη δική του κατάσταση και δεν
ενεργοποιεί ποτέ επανα-renderάρισμα του React. Πρέπει να εγγραφείτε χειροκίνητα
στις αλλαγές κατάστασης.
Is this page helpful?