Τεκμηρίωση SolanaΓρήγορη Έναρξη

React Hooks

Το πακέτο @solana-commerce/sdk παρέχει React hooks για τη δημιουργία προσαρμοσμένων εμπειριών πληρωμών Solana. Αυτά τα hooks προσφέρουν πλήρη έλεγχο των μεταφορών SOL και SPL token με ενσωματωμένη διαχείριση κατάστασης, αυτόματη λογική επανάληψης, διαχείριση σφαλμάτων και βοηθητικά εργαλεία UI.

Εσωτερικά, το SDK χρησιμοποιεί το TanStack Query για caching και διαχείριση κατάστασης, το @solana/kit για πρωτογενή στοιχεία Solana, και ενσωματώνεται απρόσκοπτα με το @solana-commerce/connector για σύνδεση πορτοφολιού.

Εγκατάσταση

pnpm add @solana-commerce/sdk

Ρύθμιση Provider

ArcProvider

Το ArcProvider είναι ο ριζικός provider που αρχικοποιεί το Solana RPC client, διαχειρίζεται τη διαμόρφωση δικτύου και παρέχει συνδεσιμότητα blockchain σε όλα τα hooks. Πρέπει να περιβάλλει οποιαδήποτε components που χρησιμοποιούν hooks του SDK.

Props

  • config (ArcWebClientConfig) - Αντικείμενο διαμόρφωσης για το Arc client
  • children (ReactNode) - Θυγατρικά components που θα έχουν πρόσβαση στα hooks
  • queryClient (QueryClient, προαιρετικό) - Προσαρμοσμένο TanStack Query client. Εάν δεν παρέχεται, δημιουργείται αυτόματα μια προεπιλεγμένη παρουσία εσωτερικά.

ArcWebClientConfig

Διαμόρφωση για το Arc client που ελέγχει τη συνδεσιμότητα RPC και τα επίπεδα δέσμευσης.

Υποχρεωτικά Πεδία

Ο provider ενσωματώνεται αυτόματα με το @solana-commerce/connector μέσω του useConnectorClient hook, επομένως δεν απαιτείται ρητή διαμόρφωση connector όταν χρησιμοποιείται εντός ενός ConnectorProvider.

Προαιρετικά Πεδία
  • network ('mainnet' | 'devnet' | 'testnet') - Δίκτυο Solana για σύνδεση. Προεπιλογή: 'mainnet'.

  • rpcUrl (string) - Προσαρμοσμένη διεύθυνση URL τελικού σημείου RPC. Εάν δεν παρέχεται, χρησιμοποιεί δημόσια τελικά σημεία για το επιλεγμένο δίκτυο.

  • commitment ('processed' | 'confirmed' | 'finalized') - Επίπεδο επιβεβαίωσης συναλλαγής. Προεπιλογή: 'confirmed'.

  • debug (boolean) - Ενεργοποιεί λεπτομερή καταγραφή κονσόλας για debugging. Προεπιλογή: false.

  • autoConnect (boolean) - Συνδέεται αυτόματα στο πορτοφόλι όταν το component φορτώνεται. Προεπιλογή: true.

  • storage (Storage) - Προσαρμοσμένος προσαρμογέας αποθήκευσης για τη διατήρηση των προτιμήσεων πορτοφολιού. Πρέπει να υλοποιεί:

    • getItem(key: string): string | null
    • setItem(key: string, value: string): void
    • removeItem(key: string): void

    Προεπιλογή: window.localStorage όταν είναι διαθέσιμο (μόνο για πρόγραμμα περιήγησης). Χρησιμοποιήστε το για React Native (AsyncStorage) ή προσαρμοσμένη αποθήκευση συμβατή με SSR.

Ενσωμάτωση με ConnectorProvider

Ο πάροχος ενσωματώνεται με το ConnectorProvider από το @solana-commerce/connector. Πάντα να τυλίγετε την εφαρμογή σας με το ConnectorProvider πριν από το ArcProvider:

import { ConnectorProvider } from "@solana-commerce/connector";
import { ArcProvider } from "@solana-commerce/sdk";
function App() {
return (
<ConnectorProvider config={{ autoConnect: true }}>
<ArcProvider config={{ network: "mainnet", commitment: "confirmed" }}>
<YourApp />
</ArcProvider>
</ConnectorProvider>
);
}

Βασικά Hooks

useTransferSOL

Hook για τη μεταφορά SOL με αυτόματη λογική επανάληψης, διαχείριση κατάστασης και βοηθητικές συναρτήσεις UI. Βασισμένο στο TanStack Query για caching και αποδιπλοποίηση αιτημάτων.

Υπογραφή

function useTransferSOL(
initialToInput?: string,
initialAmountInput?: string
): UseTransferSOLReturn;

Παράμετροι

  • initialToInput (string, προαιρετικό) - Αρχική τιμή για το πεδίο εισαγωγής της διεύθυνσης παραλήπτη. Χρήσιμο για την προσυμπλήρωση φορμών.
  • initialAmountInput (string, προαιρετικό) - Αρχική τιμή για το πεδίο εισαγωγής ποσού σε SOL. Χρήσιμο για την προσυμπλήρωση φορμών.

Επιστρεφόμενη Τιμή

interface UseTransferSOLReturn {
// Core transfer function
transferSOL: (options: TransferSOLOptions) => Promise<TransferSOLResult>;
// State
isLoading: boolean;
error: Error | null;
data: TransferSOLResult | null;
reset: () => void;
// UI Helpers
toInput: string;
amountInput: string;
setToInput: (value: string) => void;
setAmountInput: (value: string) => void;
handleToInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
handleAmountInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
handleSubmit: (event?: {
preventDefault?: () => void;
}) => Promise<TransferSOLResult | undefined>;
transferFromInputs: () => Promise<TransferSOLResult | undefined>;
}
Βασική Συνάρτηση
  • transferSOL - Ξεκινά μια μεταφορά SOL. Επιστρέφει ένα promise που επιλύεται όταν η συναλλαγή επιβεβαιωθεί on-chain.
Ιδιότητες Κατάστασης
  • isLoading (boolean) - true ενώ η συναλλαγή επεξεργάζεται (υπογραφή, υποβολή, επιβεβαίωση). Χρησιμοποιήστε το για δείκτες φόρτωσης και καταστάσεις κουμπιών.

  • error (Error | null) - Αντικείμενο σφάλματος εάν η συναλλαγή απέτυχε σε οποιοδήποτε στάδιο. null όταν δεν υπάρχει σφάλμα. Τα σφάλματα περιλαμβάνουν απορρίψεις πορτοφολιού, ανεπαρκές υπόλοιπο, αποτυχίες δικτύου κ.λπ.

  • data (TransferSOLResult | null) - Αντικείμενο αποτελέσματος όταν η συναλλαγή επιτύχει. Περιέχει υπογραφή, διευθύνσεις, ποσά και μεταδεδομένα blockchain. null πριν από την πρώτη επιτυχημένη μεταφορά.

  • reset (() => void) - Επαναφέρει την κατάσταση mutation, καθαρίζοντας τα error και data. Χρήσιμο για ροές επανάληψης ή επαναφορά φορμών μετά την ολοκλήρωση.

Βοηθητικές Ιδιότητες & Μέθοδοι UI

Το hook παρέχει ενσωματωμένη διαχείριση κατάστασης για πεδία εισαγωγής φορμών:

  • toInput / setToInput - Ελεγχόμενη κατάσταση για το πεδίο εισαγωγής διεύθυνσης παραλήπτη

  • amountInput / setAmountInput - Ελεγχόμενη κατάσταση για το πεδίο εισαγωγής ποσού (σε SOL, όχι σε lamport)

  • handleToInputChange - Προσυνδεδεμένος χειριστής onChange για την εισαγωγή παραλήπτη: <input onChange={handleToInputChange} />

  • handleAmountInputChange - Προσυνδεδεμένος χειριστής onChange για την εισαγωγή ποσού: <input onChange={handleAmountInputChange} />

  • transferFromInputs - Βοηθητική μέθοδος που μεταφέρει SOL χρησιμοποιώντας τις τρέχουσες τιμές toInput και amountInput. Μετατρέπει αυτόματα το ποσό από SOL σε lamports.

  • handleSubmit - Χειριστής υποβολής φόρμας που καλεί το transferFromInputs() και αποτρέπει την προεπιλεγμένη συμπεριφορά της φόρμας. Χρησιμοποιήστε με <form onSubmit={handleSubmit}>.

Επιλογές

interface TransferSOLOptions {
to: string | Address; // Recipient wallet address
amount: bigint; // Amount in lamports (1 SOL = 1,000,000,000 lamports)
from?: string | Address; // Optional sender address (defaults to connected wallet)
}
  • to (απαιτείται) - Διεύθυνση Solana παραλήπτη. Μπορεί να είναι string ή τύπος Address από το @solana/kit.

  • amount (απαιτείται) - Ποσό μεταφοράς σε lamports (όχι SOL). Πρέπει να είναι bigint. Χρησιμοποιήστε BigInt() ή literal σημειογραφία: 1_000_000_000n = 1 SOL.

  • from (προαιρετικό) - Διεύθυνση αποστολέα. Εάν δεν παρέχεται, χρησιμοποιεί τη διεύθυνση από το συνδεδεμένο πορτοφόλι. Απαιτείται μόνο για προηγμένες περιπτώσεις χρήσης (π.χ., υπογραφή για διαφορετικό λογαριασμό).

Αποτέλεσμα

Το αποτέλεσμα περιλαμβάνει μεταδεδομένα συναλλαγής συμπεριλαμβανομένων των λεπτομερειών μεταφοράς και της υπογραφής συναλλαγής:

interface TransferSOLResult {
signature: string; // Transaction signature (base58)
amount: bigint; // Amount transferred in lamports
from: Address; // Sender address
to: Address; // Recipient address
blockTime?: number; // Unix timestamp when transaction was processed
slot?: number; // Slot number where transaction was confirmed
}

Εσωτερική Αρχιτεκτονική

Transaction Builder: Το hook χρησιμοποιεί έναν κοινόχρηστο δημιουργό συναλλαγών που:

  • Ανακτά ανανεωμένα blockhashes για κάθε συναλλαγή
  • Δημιουργεί βελτιστοποιημένα μηνύματα συναλλαγών με ελάχιστες χρεώσεις
  • Υπογράφει συναλλαγές χρησιμοποιώντας το συνδεδεμένο πορτοφόλι
  • Υποβάλλει και επιβεβαιώνει συναλλαγές σε μία ενιαία ροή

Ακύρωση Cache: Σε επιτυχημένη μεταφορά, το hook ακυρώνει αυτόματα τις TanStack Query caches για:

  • Υπόλοιπο αποστολέα (διεύθυνση from)
  • Υπόλοιπο παραλήπτη (διεύθυνση to)

Αυτό διασφαλίζει ότι οποιαδήποτε στοιχεία εμφανίζουν υπόλοιπα (π.χ., μέσω useArcClient) ανακτούν και ενημερώνουν αυτόματα χωρίς χειροκίνητη παρέμβαση.

Ακριβής Μετατροπή Ποσού: Όταν χρησιμοποιείτε το transferFromInputs(), το ποσό μετατρέπεται από SOL σε lamports χρησιμοποιώντας αριθμητική με βάση συμβολοσειρές για την αποφυγή σφαλμάτων ακρίβειας κινητής υποδιαστολής. Η μετατροπή:

  • Επικυρώνει τη μορφή εισόδου (απορρίπτει αρνητικούς, μη έγκυρους αριθμούς)
  • Χειρίζεται έως και 9 δεκαδικά ψηφία (1 lamport = 0.000000001 SOL)
  • Περικόπτει ή συμπληρώνει κλασματικές τιμές όπως απαιτείται
  • Εμφανίζει περιγραφικά σφάλματα για μη έγκυρες εισόδους

useTransferToken

Όπως το useTransferSOL, αυτό το hook χρησιμοποιείται για τη μεταφορά SPL tokens. Εκτός από τη διαχείριση μεταφορών, το hook χειρίζεται επίσης την αυτόματη δημιουργία Associated Token Account (ATA) όταν χρειάζεται.

Υπογραφή

function useTransferToken(
initialMintInput?: string,
initialToInput?: string,
initialAmountInput?: string
): UseTransferTokenReturn;

Παράμετροι

  • initialMintInput (string, προαιρετικό) - Αρχική διεύθυνση mint του token. Χρήσιμο για μεταφορές σταθερού token.

Τιμή Επιστροφής

interface UseTransferTokenReturn {
// Core transfer function
transferToken: (
options: TransferTokenOptions
) => Promise<TransferTokenResult>;
// State
isLoading: boolean;
error: Error | null;
data: TransferTokenResult | null;
reset: () => void;
// UI Helpers
mintInput: string;
toInput: string;
amountInput: string;
setMintInput: (value: string) => void;
setToInput: (value: string) => void;
setAmountInput: (value: string) => void;
handleMintInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
handleToInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
handleAmountInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
handleSubmit: (event?: {
preventDefault?: () => void;
}) => Promise<TransferTokenResult | undefined>;
transferFromInputs: () => Promise<TransferTokenResult | undefined>;
}

Η τιμή επιστροφής είναι παρόμοια με το useTransferSOL αλλά περιλαμβάνει μια πρόσθετη κατάσταση mintInput για την επιλογή token.

Επιλογές

interface TransferTokenOptions {
mint: string | Address; // Token mint address
to: string | Address; // Recipient wallet address
amount: bigint; // Amount in token's smallest unit
from?: string | Address; // Optional sender (defaults to connected wallet)
createAccountIfNeeded?: boolean; // Auto-create recipient's ATA (default: true)
retryConfig?: TransferRetryConfig; // Optional retry configuration
}
Υποχρεωτικά Πεδία
  • mint - Διεύθυνση mint του SPL token. Για παράδειγμα:

    • USDC: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
    • USDT: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'
  • to - Διεύθυνση πορτοφολιού του παραλήπτη (όχι του token account του). Το hook παράγει αυτόματα το σωστό Associated Token Account.

  • amount - Ποσό μεταφοράς στη μικρότερη μονάδα του token. Πρέπει να λαμβάνει υπόψη τα δεκαδικά ψηφία του token:

    • USDC (6 δεκαδικά): 1_000_000n = 1 USDC
    • Tokens με περιτύλιγμα SOL (9 δεκαδικά): 1_000_000_000n = 1 token
Προαιρετικά Πεδία
  • from - Διεύθυνση πορτοφολιού του αποστολέα. Προεπιλογή στο συνδεδεμένο πορτοφόλι.

  • createAccountIfNeeded (προεπιλογή: true) - Εάν ο παραλήπτης δεν έχει token account για αυτό το mint, δημιουργείται αυτόματα ως μέρος της συναλλαγής. Όταν είναι false, η μεταφορά θα αποτύχει εάν το account του παραλήπτη δεν υπάρχει.

    Σημείωση: Η δημιουργία ενός token account κοστίζει ~0.00203 SOL. Αυτό καταβάλλεται από τον αποστολέα.

  • retryConfig - Διαμόρφωση για αυτόματη επανάληψη σε περίπτωση λήξης blockhash. Δείτε Διαμόρφωση Επανάληψης.

Αποτέλεσμα

Το αποτέλεσμα περιλαμβάνει μεταδεδομένα συναλλαγής συμπεριλαμβανομένων λεπτομερειών μεταφοράς και της υπογραφής συναλλαγής:

interface TransferTokenResult {
signature: string; // Transaction signature
mint: Address; // Token mint address
amount: bigint; // Amount transferred
from: Address; // Sender wallet address
to: Address; // Recipient wallet address
fromTokenAccount: Address; // Sender's token account
toTokenAccount: Address; // Recipient's token account
createdAccount?: boolean; // Whether recipient's ATA was created
blockTime?: number; // Transaction timestamp
slot?: number; // Block slot number
}

Διαμόρφωση Επανάληψης

Το hook περιλαμβάνει εξελιγμένη λογική επανάληψης για τη διαχείριση λήξης blockhash, που συμβαίνει συχνά κατά τη διάρκεια συμφόρησης δικτύου.

interface TransferRetryConfig {
maxAttempts?: number; // Max retry attempts (default: 3)
baseDelay?: number; // Base delay in ms (default: 1000)
backoffMultiplier?: number; // Backoff multiplier (default: 1)
}
  • maxAttempts - Μέγιστος αριθμός προσπαθειών συναλλαγής. Κάθε προσπάθεια ανακτά ένα νέο blockhash. Προεπιλογή: 3.

  • baseDelay - Καθυστέρηση σε milliseconds πριν από την πρώτη επανάληψη. Προεπιλογή: 1000 (1 δευτερόλεπτο).

  • backoffMultiplier - Πολλαπλασιαστής εκθετικής υποχώρησης. Κάθε επανάληψη περιμένει baseDelay * (backoffMultiplier ^ attemptNumber) milliseconds.

    • 1 = γραμμική υποχώρηση (1s, 1s, 1s)
    • 1.5 = εκθετική υποχώρηση (1s, 1.5s, 2.25s)
    • 2 = επιθετική εκθετική (1s, 2s, 4s)

Πώς Λειτουργεί η Επανάληψη:

  1. Πρώτη Προσπάθεια: Η συναλλαγή κατασκευάζεται με το τρέχον blockhash και υποβάλλεται
  2. Λήξη Blockhash: Εάν το blockhash γίνει παρωχημένο πριν από την επιβεβαίωση, το Solana απορρίπτει τη συναλλαγή
  3. Αυτόματη Επανάληψη: Το hook εντοπίζει τη λήξη, ανακτά ένα νέο blockhash, ξαναχτίζει τη συναλλαγή και την υποβάλλει ξανά
  4. Εκθετική Υποχώρηση: Κάθε επανάληψη περιμένει περισσότερο για να αποφευχθεί η συμφόρηση δικτύου
  5. Τελική Αποτυχία: Μετά από maxAttempts, εμφανίζει BlockhashExpirationError με πλαίσιο

Πότε δεν Ενεργοποιούνται οι Επαναλήψεις:

  • Σφάλματα μη σχετικά με blockhash (ανεπαρκή κεφάλαια, μη έγκυροι λογαριασμοί κ.λπ.) εμφανίζονται άμεσα χωρίς επανάληψη
  • Μόνο σφάλματα λήξης blockhash ενεργοποιούν τον μηχανισμό επανάληψης

Εσωτερική Αρχιτεκτονική

Διαχείριση ATA:

  • Παράγει Associated Token Accounts με ντετερμινιστικό τρόπο χρησιμοποιώντας findAssociatedTokenPda (Σημείωση: μόνο το Token Program υποστηρίζεται αυτήν τη στιγμή)
  • Ελέγχει αν ο αποστολέας έχει token account (αποτυγχάνει άμεσα αν ο αποστολέας δεν κατέχει το token)
  • Ελέγχει αν ο παραλήπτης έχει token account (δημιουργεί αν χρειάζεται και createAccountIfNeeded: true)
  • Οι έλεγχοι λογαριασμών εκτελούνται μόνο στην πρώτη προσπάθεια για να αποφευχθούν πλεονάζουσες κλήσεις RPC κατά τις επαναλήψεις

Ακύρωση Cache: Σε περίπτωση επιτυχίας, ακυρώνει τις προσωρινές μνήμες του TanStack Query για:

  • Υπόλοιπο token του αποστολέα για αυτό το mint
  • Υπόλοιπο token του παραλήπτη για αυτό το mint
  • Σχετικά δεδομένα λογαριασμού

Αυτό διατηρεί όλα τα στοιχεία της διεπαφής χρήστη που εμφανίζουν υπόλοιπα αυτόματα συγχρονισμένα.

useArcClient

Hook για πρόσβαση στον υποκείμενο RPC client του Solana, την κατάσταση του πορτοφολιού και τη διαμόρφωση δικτύου. Πρόκειται για ένα hook χαμηλότερου επιπέδου για προηγμένες περιπτώσεις χρήσης που απαιτούν άμεση πρόσβαση RPC.

Υπογραφή

function useArcClient(): ArcClientSnapshot;

Τιμή Επιστροφής

interface ArcClientSnapshot {
// Wallet State
wallet: {
address: Address | null;
signer: TransactionSigner | null;
};
// Network Configuration
network: {
cluster: "mainnet" | "devnet" | "testnet";
rpcUrl: string;
};
// Client Configuration
config: ArcWebClientConfig;
// Actions
select: (walletName: string) => Promise<void>;
disconnect: () => Promise<void>;
selectAccount: (accountAddress: Address) => Promise<void>;
}
Κατάσταση

Το ArcClientSnapshot επεκτείνει το ArcWebClient το οποίο παρέχει πρόσβαση σε:

  • κατάσταση πορτοφολιού (διεύθυνση, υπογράφων, διαθέσιμα πορτοφόλια, χαρακτηριστικά και κατάσταση πορτοφολιού)
  • διαμόρφωση δικτύου (τελικό σημείο RPC, cluster Solana)

Περιπτώσεις Χρήσης

Άμεσα Ερωτήματα RPC:

import { useArcClient } from "@solana-commerce/sdk";
import { getSharedRpc } from "@solana-commerce/sdk/core/rpc-manager";
import { address } from "@solana/kit";
function AccountBalance() {
const { network, wallet } = useArcClient();
const [balance, setBalance] = useState<bigint | null>(null);
useEffect(() => {
if (!wallet.address) return;
const rpc = getSharedRpc(network.rpcUrl);
async function fetchBalance() {
const result = await rpc.getBalance(wallet.address).send();
setBalance(result);
}
fetchBalance();
}, [wallet.address, network.rpcUrl]);
if (!wallet.address) return <div>Connect wallet to see balance</div>;
return <div>Balance: {(Number(balance) / 1e9).toFixed(4)} SOL</div>;
}

Στοιχεία με Επίγνωση Δικτύου:

function NetworkIndicator() {
const { network } = useArcClient();
return (
<div>
<span>Network: {network.cluster}</span>
{network.canAirdrop && <button onClick={handleAirdrop}>Airdrop</button>}
</div>
);
}

Υπό Συνθήκη Απόδοση Βάσει Πορτοφολιού:

function SendButton() {
const { wallet } = useArcClient();
const { transferSOL, isLoading } = useTransferSOL();
if (!wallet.address) {
return <div>Connect wallet to send SOL</div>;
}
return (
<button
onClick={() =>
transferSOL({
to: "recipient-address",
amount: BigInt(1_000_000_000)
})
}
disabled={isLoading}
>
{isLoading ? "Sending..." : "Send 1 SOL"}
</button>
);
}

Is this page helpful?

Διαχειρίζεται από

© 2026 Ίδρυμα Solana.
Με επιφύλαξη παντός δικαιώματος.
Συνδεθείτε