@sodax/wallet-sdk-react 1.5.6-beta → 2.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -145
- package/ai-exported/AGENTS.md +122 -0
- package/ai-exported/integration/README.md +102 -0
- package/ai-exported/integration/ai-rules.md +136 -0
- package/ai-exported/integration/architecture.md +181 -0
- package/ai-exported/integration/examples/01-minimal-evm.tsx +75 -0
- package/ai-exported/integration/examples/02-multi-chain-modal.tsx +169 -0
- package/ai-exported/integration/examples/03-nextjs-app-router.tsx +99 -0
- package/ai-exported/integration/examples/04-walletconnect-setup.tsx +89 -0
- package/ai-exported/integration/examples/README.md +29 -0
- package/ai-exported/integration/recipes/batch-operations.md +223 -0
- package/ai-exported/integration/recipes/bridge-to-sdk.md +164 -0
- package/ai-exported/integration/recipes/chain-detection.md +254 -0
- package/ai-exported/integration/recipes/connect-button.md +156 -0
- package/ai-exported/integration/recipes/multi-chain-modal.md +199 -0
- package/ai-exported/integration/recipes/setup.md +158 -0
- package/ai-exported/integration/recipes/sign-message.md +137 -0
- package/ai-exported/integration/recipes/sub-path-imports.md +95 -0
- package/ai-exported/integration/recipes/switch-chain.md +141 -0
- package/ai-exported/integration/recipes/walletconnect-setup.md +139 -0
- package/ai-exported/integration/reference/api-surface.md +175 -0
- package/ai-exported/integration/reference/chain-support.md +78 -0
- package/ai-exported/integration/reference/connectors.md +74 -0
- package/ai-exported/integration/reference/hooks.md +204 -0
- package/ai-exported/integration/reference/wallet-brands.md +106 -0
- package/ai-exported/migration/README.md +49 -0
- package/ai-exported/migration/ai-rules.md +144 -0
- package/ai-exported/migration/breaking-changes.md +305 -0
- package/ai-exported/migration/checklist.md +159 -0
- package/ai-exported/migration/recipes/connect-button.md +166 -0
- package/ai-exported/migration/recipes/multi-chain-modal.md +244 -0
- package/ai-exported/migration/recipes/ssr-setup.md +162 -0
- package/ai-exported/migration/recipes/walletconnect-migration.md +168 -0
- package/ai-exported/migration/reference/components.md +73 -0
- package/ai-exported/migration/reference/config.md +307 -0
- package/ai-exported/migration/reference/hooks.md +278 -0
- package/ai-exported/migration/reference/imports.md +157 -0
- package/dist/XConnector-B9YQTVJ4.d.ts +146 -0
- package/dist/chunk-2BOUGCJ7.mjs +150 -0
- package/dist/chunk-2BOUGCJ7.mjs.map +1 -0
- package/dist/chunk-66BAUK56.mjs +202 -0
- package/dist/chunk-66BAUK56.mjs.map +1 -0
- package/dist/chunk-7ULB6DW4.mjs +102 -0
- package/dist/chunk-7ULB6DW4.mjs.map +1 -0
- package/dist/chunk-BKJB527E.mjs +125 -0
- package/dist/chunk-BKJB527E.mjs.map +1 -0
- package/dist/chunk-BXJLBR4G.mjs +88 -0
- package/dist/chunk-BXJLBR4G.mjs.map +1 -0
- package/dist/chunk-E5IAZ7E6.mjs +186 -0
- package/dist/chunk-E5IAZ7E6.mjs.map +1 -0
- package/dist/chunk-MAQ47Q52.mjs +33 -0
- package/dist/chunk-MAQ47Q52.mjs.map +1 -0
- package/dist/chunk-MXZVF5HR.mjs +34 -0
- package/dist/chunk-MXZVF5HR.mjs.map +1 -0
- package/dist/chunk-N5A2TMF6.mjs +33 -0
- package/dist/chunk-N5A2TMF6.mjs.map +1 -0
- package/dist/chunk-NY7U7OJW.mjs +64 -0
- package/dist/chunk-NY7U7OJW.mjs.map +1 -0
- package/dist/chunk-PJLEJVAU.mjs +140 -0
- package/dist/chunk-PJLEJVAU.mjs.map +1 -0
- package/dist/chunk-PLCA4ZDJ.mjs +1585 -0
- package/dist/chunk-PLCA4ZDJ.mjs.map +1 -0
- package/dist/chunk-TZMKDXFA.mjs +3 -0
- package/dist/chunk-TZMKDXFA.mjs.map +1 -0
- package/dist/chunk-X2MHIWXO.mjs +100 -0
- package/dist/chunk-X2MHIWXO.mjs.map +1 -0
- package/dist/chunk-XZ7CHO2S.mjs +41 -0
- package/dist/chunk-XZ7CHO2S.mjs.map +1 -0
- package/dist/config-OlnzyEUE.d.ts +146 -0
- package/dist/index.cjs +2784 -1594
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +768 -1498
- package/dist/index.mjs +463 -2004
- package/dist/index.mjs.map +1 -1
- package/dist/xchains/bitcoin/index.cjs +1927 -0
- package/dist/xchains/bitcoin/index.cjs.map +1 -0
- package/dist/xchains/bitcoin/index.d.ts +125 -0
- package/dist/xchains/bitcoin/index.mjs +16 -0
- package/dist/xchains/bitcoin/index.mjs.map +1 -0
- package/dist/xchains/evm/index.cjs +316 -0
- package/dist/xchains/evm/index.cjs.map +1 -0
- package/dist/xchains/evm/index.d.ts +39 -0
- package/dist/xchains/evm/index.mjs +5 -0
- package/dist/xchains/evm/index.mjs.map +1 -0
- package/dist/xchains/icon/index.cjs +311 -0
- package/dist/xchains/icon/index.cjs.map +1 -0
- package/dist/xchains/icon/index.d.ts +37 -0
- package/dist/xchains/icon/index.mjs +7 -0
- package/dist/xchains/icon/index.mjs.map +1 -0
- package/dist/xchains/injective/index.cjs +223 -0
- package/dist/xchains/injective/index.cjs.map +1 -0
- package/dist/xchains/injective/index.d.ts +35 -0
- package/dist/xchains/injective/index.mjs +5 -0
- package/dist/xchains/injective/index.mjs.map +1 -0
- package/dist/xchains/near/index.cjs +190 -0
- package/dist/xchains/near/index.cjs.map +1 -0
- package/dist/xchains/near/index.d.ts +34 -0
- package/dist/xchains/near/index.mjs +6 -0
- package/dist/xchains/near/index.mjs.map +1 -0
- package/dist/xchains/solana/index.cjs +186 -0
- package/dist/xchains/solana/index.cjs.map +1 -0
- package/dist/xchains/solana/index.d.ts +26 -0
- package/dist/xchains/solana/index.mjs +7 -0
- package/dist/xchains/solana/index.mjs.map +1 -0
- package/dist/xchains/stacks/index.cjs +240 -0
- package/dist/xchains/stacks/index.cjs.map +1 -0
- package/dist/xchains/stacks/index.d.ts +36 -0
- package/dist/xchains/stacks/index.mjs +5 -0
- package/dist/xchains/stacks/index.mjs.map +1 -0
- package/dist/xchains/stellar/index.cjs +322 -0
- package/dist/xchains/stellar/index.cjs.map +1 -0
- package/dist/xchains/stellar/index.d.ts +44 -0
- package/dist/xchains/stellar/index.mjs +6 -0
- package/dist/xchains/stellar/index.mjs.map +1 -0
- package/dist/xchains/sui/index.cjs +248 -0
- package/dist/xchains/sui/index.cjs.map +1 -0
- package/dist/xchains/sui/index.d.ts +37 -0
- package/dist/xchains/sui/index.mjs +7 -0
- package/dist/xchains/sui/index.mjs.map +1 -0
- package/docs/ADDING_A_NEW_CHAIN.md +440 -0
- package/docs/ARCHITECTURE.md +291 -0
- package/docs/BATCH_OPERATIONS.md +267 -0
- package/docs/CHAIN_DETECTION.md +216 -0
- package/docs/CONFIGURE_PROVIDER.md +360 -0
- package/docs/CONNECTORS.md +247 -0
- package/docs/CONNECT_FLOW.md +276 -0
- package/docs/EVM_SWITCH_CHAIN.md +161 -0
- package/docs/SIGN_MESSAGE.md +213 -0
- package/docs/SUB_PATH_EXPORTS.md +246 -0
- package/docs/WALLETCONNECT.md +154 -0
- package/docs/WALLET_MODAL.md +331 -0
- package/docs/WALLET_PROVIDER_BRIDGE.md +226 -0
- package/package.json +34 -9
- package/skills/SKILLS.md +84 -0
- package/skills/bridge-to-sdk.md +148 -0
- package/skills/connect-button.md +116 -0
- package/skills/evm-only-walletconnect.md +111 -0
- package/skills/multi-chain-modal.md +178 -0
- package/skills/setup.md +107 -0
- package/dist/index.d.cts +0 -1579
- package/src/Hydrate.ts +0 -65
- package/src/SodaxWalletProvider.tsx +0 -97
- package/src/actions/getXChainType.ts +0 -8
- package/src/actions/getXService.ts +0 -33
- package/src/actions/index.ts +0 -2
- package/src/assets/wallets/hana.svg +0 -6
- package/src/assets/wallets/havah.svg +0 -76
- package/src/assets/wallets/keplr.svg +0 -30
- package/src/assets/wallets/metamask.svg +0 -60
- package/src/assets/wallets/phantom.svg +0 -4
- package/src/assets/wallets/sui.svg +0 -20
- package/src/core/XConnector.ts +0 -54
- package/src/core/XService.ts +0 -85
- package/src/core/index.ts +0 -2
- package/src/hooks/index.ts +0 -11
- package/src/hooks/useEthereumChainId.ts +0 -44
- package/src/hooks/useEvmSwitchChain.ts +0 -91
- package/src/hooks/useWalletProvider.ts +0 -206
- package/src/hooks/useXAccount.ts +0 -51
- package/src/hooks/useXAccounts.ts +0 -56
- package/src/hooks/useXBalances.ts +0 -65
- package/src/hooks/useXConnect.ts +0 -118
- package/src/hooks/useXConnection.ts +0 -72
- package/src/hooks/useXConnectors.ts +0 -72
- package/src/hooks/useXDisconnect.ts +0 -73
- package/src/hooks/useXService.ts +0 -8
- package/src/hooks/useXSignMessage.ts +0 -82
- package/src/index.ts +0 -19
- package/src/types/index.ts +0 -22
- package/src/useXWagmiStore.ts +0 -116
- package/src/utils/index.ts +0 -21
- package/src/xchains/bitcoin/BitcoinXConnector.ts +0 -34
- package/src/xchains/bitcoin/BitcoinXService.ts +0 -40
- package/src/xchains/bitcoin/OKXXConnector.ts +0 -117
- package/src/xchains/bitcoin/UnisatXConnector.ts +0 -117
- package/src/xchains/bitcoin/XverseXConnector.ts +0 -232
- package/src/xchains/bitcoin/index.ts +0 -7
- package/src/xchains/bitcoin/useBitcoinXConnectors.ts +0 -14
- package/src/xchains/evm/EvmXConnector.ts +0 -27
- package/src/xchains/evm/EvmXService.ts +0 -211
- package/src/xchains/evm/index.ts +0 -3
- package/src/xchains/icon/IconHanaXConnector.ts +0 -39
- package/src/xchains/icon/IconXService.ts +0 -117
- package/src/xchains/icon/actions.ts +0 -28
- package/src/xchains/icon/iconex/index.tsx +0 -46
- package/src/xchains/icon/index.ts +0 -2
- package/src/xchains/injective/InjectiveXConnector.ts +0 -60
- package/src/xchains/injective/InjectiveXService.ts +0 -62
- package/src/xchains/injective/actions.ts +0 -32
- package/src/xchains/injective/index.ts +0 -2
- package/src/xchains/near/NearXConnector.ts +0 -42
- package/src/xchains/near/NearXService.ts +0 -46
- package/src/xchains/near/useNearXConnectors.ts +0 -23
- package/src/xchains/solana/SolanaXConnector.ts +0 -26
- package/src/xchains/solana/SolanaXService.ts +0 -46
- package/src/xchains/solana/index.ts +0 -2
- package/src/xchains/stacks/StacksXConnector.ts +0 -63
- package/src/xchains/stacks/StacksXService.ts +0 -59
- package/src/xchains/stacks/constants.ts +0 -42
- package/src/xchains/stacks/index.ts +0 -4
- package/src/xchains/stacks/useStacksXConnectors.ts +0 -7
- package/src/xchains/stellar/CustomSorobanServer.ts +0 -93
- package/src/xchains/stellar/StellarWalletsKitXConnector.ts +0 -53
- package/src/xchains/stellar/StellarXService.ts +0 -93
- package/src/xchains/stellar/actions.ts +0 -24
- package/src/xchains/stellar/index.tsx +0 -2
- package/src/xchains/stellar/useStellarXConnectors.ts +0 -21
- package/src/xchains/stellar/utils.ts +0 -49
- package/src/xchains/sui/SuiXConnector.ts +0 -28
- package/src/xchains/sui/SuiXService.ts +0 -66
- package/src/xchains/sui/index.ts +0 -2
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# Connectors
|
|
2
|
+
|
|
3
|
+
A connector is the adapter between a specific wallet (Hana, MetaMask, Phantom, Xverse…) and the SODAX store. Every connector implements `IXConnector`, the public contract every hook in `wallet-sdk-react` consumes. The base abstract class `XConnector` provides default `isInstalled` / `installUrl` semantics that subclasses override per wallet.
|
|
4
|
+
|
|
5
|
+
Concrete connector and service classes are **not** exported from the package barrel — they live behind sub-path imports under `@sodax/wallet-sdk-react/xchains/<chain>` to prevent accidental coupling.
|
|
6
|
+
|
|
7
|
+
## Table of contents
|
|
8
|
+
|
|
9
|
+
1. [`IXConnector` interface](#ixconnector-interface)
|
|
10
|
+
2. [`XConnector` abstract base](#xconnector-abstract-base)
|
|
11
|
+
3. [Sub-path imports — concrete classes](#sub-path-imports--concrete-classes)
|
|
12
|
+
4. [Per-chain connector reference](#per-chain-connector-reference)
|
|
13
|
+
5. [Discovery — EIP-6963 vs adapter vs window probe](#discovery--eip-6963-vs-adapter-vs-window-probe)
|
|
14
|
+
6. [`sortConnectors` — display ordering](#sortconnectors--display-ordering)
|
|
15
|
+
7. [Custom connectors](#custom-connectors)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## `IXConnector` interface
|
|
20
|
+
|
|
21
|
+
Defined in [`src/types/interfaces.ts`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/src/types/interfaces.ts):
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
export interface IXConnector {
|
|
25
|
+
readonly xChainType: ChainType;
|
|
26
|
+
readonly name: string; // 'Hana', 'MetaMask', 'Xverse', …
|
|
27
|
+
readonly _id: string; // unique connector id (e.g. 'io.metamask')
|
|
28
|
+
readonly _icon?: string; // raw icon URL (or undefined)
|
|
29
|
+
|
|
30
|
+
readonly id: string; // public getter — same as _id
|
|
31
|
+
readonly icon: string | undefined; // public getter
|
|
32
|
+
|
|
33
|
+
readonly isInstalled: boolean; // wallet extension presence (read at getter call time)
|
|
34
|
+
readonly installUrl: string | undefined;
|
|
35
|
+
|
|
36
|
+
connect(): Promise<XAccount | undefined>;
|
|
37
|
+
disconnect(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Consumer code should depend on **`IXConnector`** (the interface), not the concrete `XConnector` class — this keeps your code chain-implementation-agnostic and allows custom connectors to slot in without inheriting from the abstract base.
|
|
42
|
+
|
|
43
|
+
`isInstalled` reads `window.*` at getter-call time — no extra subscription is installed. Components get fresh values through normal React render triggers (store updates, parent re-renders).
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## `XConnector` abstract base
|
|
48
|
+
|
|
49
|
+
The default class subclasses extend ([`src/core/XConnector.ts`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/src/core/XConnector.ts)):
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
export abstract class XConnector implements IXConnector {
|
|
53
|
+
public readonly xChainType: ChainType;
|
|
54
|
+
public readonly name: string;
|
|
55
|
+
public readonly _id: string;
|
|
56
|
+
public readonly _icon?: string;
|
|
57
|
+
|
|
58
|
+
constructor(xChainType: ChainType, name: string, id: string) { ... }
|
|
59
|
+
|
|
60
|
+
abstract connect(): Promise<XAccount | undefined>;
|
|
61
|
+
abstract disconnect(): Promise<void>;
|
|
62
|
+
|
|
63
|
+
get id(): string { return this._id; }
|
|
64
|
+
get icon(): string | undefined { return this._icon; }
|
|
65
|
+
|
|
66
|
+
/** Default: true. Override in subclasses backed by extension injection. */
|
|
67
|
+
get isInstalled(): boolean { return true; }
|
|
68
|
+
get installUrl(): string | undefined { return undefined; }
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The `isInstalled = true` default is correct for **provider-managed chains** (EVM via EIP-6963, Solana via wallet-adapter discovery, Sui via dapp-kit) — if the connector exists in the store, the underlying extension was found by the native SDK.
|
|
73
|
+
|
|
74
|
+
Browser-extension chains (Bitcoin, ICON, Stacks) override `isInstalled` with a `window.unisat` / `window.hanaWallet` / `window.LeatherProvider` probe, plus an `installUrl` to point users to the Chrome Web Store entry.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Sub-path imports — concrete classes
|
|
79
|
+
|
|
80
|
+
The package barrel `@sodax/wallet-sdk-react` deliberately omits concrete classes — only types/interfaces and hooks are exported. To get a concrete class for `instanceof` checks or chain-specific methods, deep-import:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// ✅ Normal usage — barrel
|
|
84
|
+
import { useXConnect, useXAccount, type IXConnector } from '@sodax/wallet-sdk-react';
|
|
85
|
+
|
|
86
|
+
// ✅ Advanced — concrete class
|
|
87
|
+
import { XverseXConnector } from '@sodax/wallet-sdk-react/xchains/bitcoin';
|
|
88
|
+
|
|
89
|
+
if (connector instanceof XverseXConnector) {
|
|
90
|
+
connector.setAddressPurpose('payment');
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The `package.json` `exports` field maps `./xchains/*` to `dist/xchains/*/index.{mjs,cjs}` and `typesVersions` adds the `node` resolution fallback.
|
|
95
|
+
|
|
96
|
+
### Sub-path map
|
|
97
|
+
|
|
98
|
+
| Sub-path | Exports |
|
|
99
|
+
|----------|---------|
|
|
100
|
+
| `@sodax/wallet-sdk-react/xchains/evm` | `EvmXService`, `EvmXConnector`, `createWagmiConfig` (alias `createWagmi`) |
|
|
101
|
+
| `@sodax/wallet-sdk-react/xchains/solana` | `SolanaXService`, `SolanaXConnector` |
|
|
102
|
+
| `@sodax/wallet-sdk-react/xchains/sui` | `SuiXService`, `SuiXConnector` |
|
|
103
|
+
| `@sodax/wallet-sdk-react/xchains/bitcoin` | `BitcoinXService`, `BitcoinXConnector`, `UnisatXConnector`, `XverseXConnector`, `OKXXConnector`, `useBitcoinXConnectors`, type `BtcWalletAddressType` |
|
|
104
|
+
| `@sodax/wallet-sdk-react/xchains/stellar` | `StellarXService`, `StellarWalletsKitXConnector` |
|
|
105
|
+
| `@sodax/wallet-sdk-react/xchains/injective` | `InjectiveXService`, `InjectiveXConnector` |
|
|
106
|
+
| `@sodax/wallet-sdk-react/xchains/icon` | `IconXService`, `IconHanaXConnector`, `CHAIN_INFO`, `SupportedChainId` |
|
|
107
|
+
| `@sodax/wallet-sdk-react/xchains/near` | `NearXService`, `NearXConnector` |
|
|
108
|
+
| `@sodax/wallet-sdk-react/xchains/stacks` | `StacksXService`, `StacksXConnector`, `STACKS_PROVIDERS`, `useStacksXConnectors`, type `StacksProviderConfig` |
|
|
109
|
+
|
|
110
|
+
`StellarXService`, `XverseXConnector`, `BtcWalletAddressType` are **also** re-exported from the barrel as `export type` (no runtime class) — those imports work either way.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Per-chain connector reference
|
|
115
|
+
|
|
116
|
+
| Chain | Connector class(es) | Discovery | Native SDK |
|
|
117
|
+
|-------|---------------------|-----------|------------|
|
|
118
|
+
| EVM | `EvmXConnector` | EIP-6963 + wagmi connectors | `wagmi` + `viem` |
|
|
119
|
+
| Solana | `SolanaXConnector` | `@solana/wallet-adapter-react` | `@solana/web3.js` |
|
|
120
|
+
| Sui | `SuiXConnector` | `@mysten/dapp-kit` | `@mysten/sui` |
|
|
121
|
+
| Stellar | `StellarWalletsKitXConnector` | async — `walletsKit.getSupportedWallets()` | `@creit.tech/stellar-wallets-kit` |
|
|
122
|
+
| Injective | `InjectiveXConnector` × 3 (MetaMask, Keplr, Leap) | wallet-base wallet types | `@injectivelabs/sdk-ts` |
|
|
123
|
+
| ICON | `IconHanaXConnector` | `window.hanaWallet` probe | `icon-sdk-js` |
|
|
124
|
+
| Bitcoin | `UnisatXConnector`, `XverseXConnector`, `OKXXConnector` | `window.unisat`, `window.XverseProviders`, `window.okxwallet.bitcoin` | `sats-connect` (Xverse), connector-specific (Unisat, OKX) |
|
|
125
|
+
| NEAR | `NearXConnector` | `@hot-labs/near-connect` | `near-api-js` |
|
|
126
|
+
| Stacks | `StacksXConnector` × N (one per registered provider) | provider list + `window.LeatherProvider` probe | `@stacks/connect` |
|
|
127
|
+
|
|
128
|
+
The `BitcoinXConnector` is an abstract base — concrete subclasses (Unisat, Xverse, OKX) implement `signEcdsaMessage` / `signBip322Message` per wallet's API. See [`SIGN_MESSAGE.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/SIGN_MESSAGE.md) for the dispatch logic.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Discovery — EIP-6963 vs adapter vs window probe
|
|
133
|
+
|
|
134
|
+
Connectors land in the store via three discovery patterns:
|
|
135
|
+
|
|
136
|
+
**Synchronous default list** (most chains) — `chainRegistry.<CHAIN>.defaultConnectors()` returns a static array at `initChainServices()` time. Bitcoin always registers Unisat + Xverse + OKX; Injective registers MetaMask + Keplr + Leap.
|
|
137
|
+
|
|
138
|
+
**Async discovery** — Stellar's connectors come from `walletsKit.getSupportedWallets()` which probes for installed Stellar wallets at runtime. Implemented via `chainRegistry.STELLAR.discoverConnectors`, called as a side-effect during init.
|
|
139
|
+
|
|
140
|
+
**Native SDK adapter** — EVM, Solana, Sui delegate to wagmi / wallet-adapter / dapp-kit. The adapter discovers wallets via EIP-6963 announcements (EVM) or vendor-specific extension protocols, and the chain's Hydrator reads the discovered list and writes it to the store.
|
|
141
|
+
|
|
142
|
+
Once in the store, all three patterns surface uniformly through `useXConnectors({ xChainType })` — consumers can't tell them apart.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## `sortConnectors` — display ordering
|
|
147
|
+
|
|
148
|
+
Pure utility for ranking connectors in lists. Stable sort by:
|
|
149
|
+
|
|
150
|
+
1. Position in `preferred[]` (earlier wins)
|
|
151
|
+
2. `isInstalled === true`
|
|
152
|
+
3. Original index
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { useXConnectors, sortConnectors } from '@sodax/wallet-sdk-react';
|
|
156
|
+
|
|
157
|
+
const PREFERRED = ['hana', 'metamask'];
|
|
158
|
+
|
|
159
|
+
function ConnectorList() {
|
|
160
|
+
const raw = useXConnectors({ xChainType: 'EVM' });
|
|
161
|
+
const sorted = sortConnectors(raw, { preferred: PREFERRED });
|
|
162
|
+
// Hana first if present, then MetaMask, then any other installed wallets, then uninstalled.
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`preferred` matches by exact `connector.id`. For substring/case-insensitive matching across chains (matches the batch-operation API), use [`useIsWalletInstalled`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CHAIN_DETECTION.md#useiswalletinstalled--install-detection) instead.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Custom connectors
|
|
171
|
+
|
|
172
|
+
Two ways to plug in a wallet the SDK doesn't ship:
|
|
173
|
+
|
|
174
|
+
### Option 1 — extend `XConnector`
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { XConnector } from '@sodax/wallet-sdk-react'; // base class is exported from barrel
|
|
178
|
+
import type { XAccount } from '@sodax/wallet-sdk-react';
|
|
179
|
+
|
|
180
|
+
class MyEvmConnector extends XConnector {
|
|
181
|
+
constructor() {
|
|
182
|
+
super('EVM', 'My Wallet', 'com.mycompany.wallet');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
override get isInstalled(): boolean {
|
|
186
|
+
return typeof window !== 'undefined' && 'mywallet' in window;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
override get installUrl(): string {
|
|
190
|
+
return 'https://chrome.google.com/webstore/detail/...';
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async connect(): Promise<XAccount | undefined> {
|
|
194
|
+
const accounts = await window.mywallet.request({ method: 'eth_requestAccounts' });
|
|
195
|
+
return accounts[0]
|
|
196
|
+
? { address: accounts[0], xChainType: 'EVM' }
|
|
197
|
+
: undefined;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async disconnect(): Promise<void> {
|
|
201
|
+
await window.mywallet.request({ method: 'wallet_revokePermissions' });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Pass it via `SodaxWalletConfig.<CHAIN>.connectors`:
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const config: SodaxWalletConfig = {
|
|
210
|
+
EVM: {
|
|
211
|
+
connectors: [new MyEvmConnector(), /* …or omit and the registry's defaults run instead */],
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The `connectors` field on a chain-type slot **replaces** the registry defaults for that chain. Include the SDK's defaults in the array if you want them alongside your custom one.
|
|
217
|
+
|
|
218
|
+
### Option 2 — implement `IXConnector` directly
|
|
219
|
+
|
|
220
|
+
Skip `XConnector` if you already have a class hierarchy and don't want the abstract base. Just implement every property/method on `IXConnector`. The SDK never does an `instanceof XConnector` check on user-supplied connectors — it only relies on the interface.
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
class MyConnector implements IXConnector {
|
|
224
|
+
readonly xChainType = 'EVM';
|
|
225
|
+
readonly name = 'My Wallet';
|
|
226
|
+
readonly _id = 'com.mycompany.wallet';
|
|
227
|
+
readonly id = this._id;
|
|
228
|
+
readonly icon = undefined;
|
|
229
|
+
get isInstalled() { /* … */ }
|
|
230
|
+
get installUrl() { /* … */ }
|
|
231
|
+
async connect() { /* … */ }
|
|
232
|
+
async disconnect() { /* … */ }
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
For chains with custom `signMessage` requirements (Bitcoin, Injective), implement the chain-specific extra methods (`signBip322Message` / `signEcdsaMessage` for Bitcoin) — `chainRegistry` checks for them via type guards at dispatch time.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Related docs
|
|
241
|
+
|
|
242
|
+
- [Configure SodaxWalletProvider](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONFIGURE_PROVIDER.md) — `connectors` slot field for overriding defaults
|
|
243
|
+
- [Connect Flow](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONNECT_FLOW.md) — how `useXConnectors` returns these connectors
|
|
244
|
+
- [Sign Message](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/SIGN_MESSAGE.md) — Bitcoin connector subclass dispatch (BIP-322 vs ECDSA)
|
|
245
|
+
- [Batch Operations](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/BATCH_OPERATIONS.md) — identifier-based connector matching
|
|
246
|
+
- [Wallet Modal](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/WALLET_MODAL.md) — `selectWallet(connector)` consumes `IXConnector`
|
|
247
|
+
- [SDK Wallet Providers Reference](https://github.com/icon-project/sodax-sdks/blob/main/packages/sdk/docs/WALLET_PROVIDERS.md) — the `IXxxWalletProvider` interfaces these connectors back into
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# Connect Flow
|
|
2
|
+
|
|
3
|
+
The connect flow covers the full wallet lifecycle in `@sodax/wallet-sdk-react`: discover available connectors → connect to a wallet → read connected account state → disconnect. Every hook reads from the central Zustand store — no direct chain-SDK hook usage in user code.
|
|
4
|
+
|
|
5
|
+
The canonical hook surface is exported from [`src/hooks/index.ts`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/src/hooks/index.ts).
|
|
6
|
+
|
|
7
|
+
## Table of contents
|
|
8
|
+
|
|
9
|
+
1. [Lifecycle overview](#lifecycle-overview)
|
|
10
|
+
2. [Discover connectors](#discover-connectors)
|
|
11
|
+
3. [Connect a wallet](#connect-a-wallet)
|
|
12
|
+
4. [Read connected account state](#read-connected-account-state)
|
|
13
|
+
5. [Disconnect](#disconnect)
|
|
14
|
+
6. [Provider-managed chains caveat](#provider-managed-chains-caveat)
|
|
15
|
+
7. [Persisted connections](#persisted-connections)
|
|
16
|
+
8. [Error handling](#error-handling)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Lifecycle overview
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
useXConnectors → user picks a connector → useXConnect.mutateAsync(connector)
|
|
24
|
+
│ │
|
|
25
|
+
│ ↓
|
|
26
|
+
│ ChainActions.connect(connectorId)
|
|
27
|
+
│ │
|
|
28
|
+
│ ↓
|
|
29
|
+
│ setXConnection(xChainType, { xAccount, xConnectorId })
|
|
30
|
+
│ │
|
|
31
|
+
↓ ↓
|
|
32
|
+
useXAccount(xChainType) ←───────────── Zustand store ─────────────→ useXConnection(xChainType)
|
|
33
|
+
│
|
|
34
|
+
↓
|
|
35
|
+
useXDisconnect({ xChainType })
|
|
36
|
+
│
|
|
37
|
+
↓
|
|
38
|
+
ChainActions.disconnect()
|
|
39
|
+
│
|
|
40
|
+
↓
|
|
41
|
+
clearXConnection(xChainType)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Single store, single source of truth** — every hook subscribes to the same Zustand slice. Connect mutations write through `setXConnection`; reads (`useXAccount`, `useXConnection`) reflect that immediately. Provider-managed chains (EVM/Solana/Sui) write via their Hydrator components instead of inside the mutation — see [Provider-managed chains caveat](#provider-managed-chains-caveat).
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Discover connectors
|
|
49
|
+
|
|
50
|
+
### `useXConnectors({ xChainType })` — connectors for one chain type
|
|
51
|
+
|
|
52
|
+
Returns the list of available connectors for a single chain family. Pass `xChainType` (`'EVM' | 'SOLANA' | 'BITCOIN' | …`).
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { useXConnectors } from '@sodax/wallet-sdk-react';
|
|
56
|
+
|
|
57
|
+
function EvmWalletList() {
|
|
58
|
+
const connectors = useXConnectors({ xChainType: 'EVM' });
|
|
59
|
+
// connectors: IXConnector[] with { id, name, icon, isInstalled, installUrl, xChainType }
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If the chain isn't enabled in `SodaxWalletProvider` config, `useXConnectors` returns `[]` and logs a one-time warning per chain.
|
|
64
|
+
|
|
65
|
+
`connector.isInstalled` reads `window.*` at render time (no extra subscription) — values stay fresh through normal React render triggers (store updates, parent re-renders).
|
|
66
|
+
|
|
67
|
+
### `useXConnectorsByChain()` — all chains at once
|
|
68
|
+
|
|
69
|
+
Returns connectors grouped by chain type. Useful for multi-chain wallet pickers.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { useXConnectorsByChain } from '@sodax/wallet-sdk-react';
|
|
73
|
+
|
|
74
|
+
function MultiChainPicker() {
|
|
75
|
+
const byChain = useXConnectorsByChain();
|
|
76
|
+
// byChain: Partial<Record<ChainType, IXConnector[]>>
|
|
77
|
+
// e.g. { EVM: [...], SOLANA: [...], BITCOIN: [...] }
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `sortConnectors(connectors, { preferred })` — display ordering
|
|
82
|
+
|
|
83
|
+
Pure utility that sorts a connector list **stably** by:
|
|
84
|
+
1. Position in `preferred[]` (earlier wins)
|
|
85
|
+
2. `isInstalled === true`
|
|
86
|
+
3. Original order
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { useXConnectors, sortConnectors } from '@sodax/wallet-sdk-react';
|
|
90
|
+
|
|
91
|
+
const PREFERRED = ['hana', 'metamask'] as const;
|
|
92
|
+
|
|
93
|
+
function ConnectorList() {
|
|
94
|
+
const raw = useXConnectors({ xChainType: 'EVM' });
|
|
95
|
+
const connectors = sortConnectors(raw, { preferred: PREFERRED });
|
|
96
|
+
// Hana first if installed, then MetaMask, then any other installed wallets, then uninstalled.
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Connect a wallet
|
|
103
|
+
|
|
104
|
+
`useXConnect()` returns a React Query mutation. Pass an `IXConnector` to `mutate` / `mutateAsync` — the hook delegates to the chain's `ChainActions.connect()` and writes the connection state into the store on success.
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { useXConnect, useXConnectors, useXAccount } from '@sodax/wallet-sdk-react';
|
|
108
|
+
|
|
109
|
+
function ConnectButton() {
|
|
110
|
+
const connectors = useXConnectors({ xChainType: 'EVM' });
|
|
111
|
+
const { mutateAsync: connect, isPending, error } = useXConnect();
|
|
112
|
+
const account = useXAccount({ xChainType: 'EVM' });
|
|
113
|
+
|
|
114
|
+
if (account.address) {
|
|
115
|
+
return <span>Connected: {account.address}</span>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<div>
|
|
120
|
+
{connectors.map(connector => (
|
|
121
|
+
<button
|
|
122
|
+
key={connector.id}
|
|
123
|
+
onClick={() => connect(connector)}
|
|
124
|
+
disabled={isPending}
|
|
125
|
+
>
|
|
126
|
+
{connector.icon && <img src={connector.icon} alt="" width={20} height={20} />}
|
|
127
|
+
{connector.name}
|
|
128
|
+
</button>
|
|
129
|
+
))}
|
|
130
|
+
{error && <p style={{ color: 'red' }}>{error.message}</p>}
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The mutation throws `Error('Chain "<X>" is not enabled or ChainActions not registered')` if the connector's chain type isn't mounted in `SodaxWalletProvider` config.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Read connected account state
|
|
141
|
+
|
|
142
|
+
Four read hooks expose the same store data at different granularities:
|
|
143
|
+
|
|
144
|
+
| Hook | Returns | Use case |
|
|
145
|
+
|------|---------|----------|
|
|
146
|
+
| `useXAccount({ xChainId })` | `XAccount` for the chain's family (resolves chain id → chain type) | Signing/reading at chain-id level (e.g. `useXAccount({ xChainId: ChainKeys.BSC_MAINNET })`) |
|
|
147
|
+
| `useXAccount({ xChainType })` | `XAccount` for that family | Family-level UI (e.g. EVM badge — one wagmi connection covers all 12 EVM chains) |
|
|
148
|
+
| `useXAccounts()` | `Partial<Record<ChainType, XAccount>>` for every enabled chain | Account list / multi-chain dashboard |
|
|
149
|
+
| `useXConnection({ xChainType })` | `XConnection \| undefined` | When you also need `xConnectorId` (e.g. to drive disconnect UX) |
|
|
150
|
+
| `useXConnections()` | `Partial<Record<ChainType, XConnection>>` | Aggregate UIs that care about connector identity per chain |
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { useXAccount, useXAccounts, useXConnection } from '@sodax/wallet-sdk-react';
|
|
154
|
+
import { ChainKeys } from '@sodax/types';
|
|
155
|
+
|
|
156
|
+
// By chain id — narrows to EVM family
|
|
157
|
+
const evmAccount = useXAccount({ xChainId: ChainKeys.BSC_MAINNET });
|
|
158
|
+
// evmAccount: { address: '0x...' | undefined, xChainType: 'EVM', publicKey?: string }
|
|
159
|
+
|
|
160
|
+
// By chain type — same data, family-level UI
|
|
161
|
+
const solanaAccount = useXAccount({ xChainType: 'SOLANA' });
|
|
162
|
+
|
|
163
|
+
// All connected accounts at once
|
|
164
|
+
const accounts = useXAccounts();
|
|
165
|
+
// accounts.EVM, accounts.SOLANA, accounts.BITCOIN, ...
|
|
166
|
+
|
|
167
|
+
// With connector identity (for disconnect button labels, etc.)
|
|
168
|
+
const evmConnection = useXConnection({ xChainType: 'EVM' });
|
|
169
|
+
// evmConnection: { xAccount: XAccount, xConnectorId: string } | undefined
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**`xChainId` vs `xChainType`** — `useXAccount` and `useWalletProvider` accept either, never both. `xChainId` (a `SpokeChainKey` like `ChainKeys.BSC_MAINNET`) is resolved to its family via `getXChainType()` internally. For EVM, the family-level view is correct because wagmi maintains a single connection across all configured EVM networks (see [`EVM_SWITCH_CHAIN.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/EVM_SWITCH_CHAIN.md)).
|
|
173
|
+
|
|
174
|
+
When no wallet is connected, `useXAccount` returns `{ address: undefined, xChainType }` (not `undefined`) so consumers don't need to null-check before reading `xChainType`.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Disconnect
|
|
179
|
+
|
|
180
|
+
`useXDisconnect()` returns a callback. Invoke with the chain type to disconnect:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
import { useXDisconnect } from '@sodax/wallet-sdk-react';
|
|
184
|
+
|
|
185
|
+
function DisconnectButton() {
|
|
186
|
+
const disconnect = useXDisconnect();
|
|
187
|
+
return <button onClick={() => disconnect({ xChainType: 'EVM' })}>Disconnect EVM</button>;
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The callback delegates to `ChainActions.disconnect()`. If no actions are registered (chain not enabled in config), it logs a warning and resolves silently — no throw. Connection state is cleared by the chain's action implementation (provider-managed) or by the store side-effect (non-provider).
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Provider-managed chains caveat
|
|
196
|
+
|
|
197
|
+
EVM, Solana, and Sui mount their native React adapters (wagmi, `@solana/wallet-adapter`, `@mysten/dapp-kit`) and use a **Provider/Hydrator/Actions trio**:
|
|
198
|
+
|
|
199
|
+
- `<ChainProvider>` — wraps native adapter context.
|
|
200
|
+
- `<ChainHydrator>` — sole writer of connection state into the store, watching native adapter hooks.
|
|
201
|
+
- `<ChainActions>` — registers `ChainActions.connect/disconnect` that trigger native SDK operations only.
|
|
202
|
+
|
|
203
|
+
Because of this split, **`useXConnect.mutateAsync(connector)` resolves with `undefined`** for EVM/Solana/Sui — connection state lands asynchronously when the Hydrator observes the wallet adapter's status flip from `disconnected` → `connected`. Read the connected account via `useXAccount` / `useXConnection` instead:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const { mutateAsync: connect } = useXConnect();
|
|
207
|
+
const account = useXAccount({ xChainType: 'EVM' });
|
|
208
|
+
|
|
209
|
+
await connect(connector); // may resolve before account.address is populated
|
|
210
|
+
// Don't read connect's return value — read account.address from the next render.
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Non-provider chains (Bitcoin, ICON, Injective, Stellar, NEAR, Stacks) write the connection state inside the mutation, so the resolved `XAccount` is reliable for those chains. Code defensively if you support both.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Persisted connections
|
|
218
|
+
|
|
219
|
+
Connection state is persisted to `localStorage` (key: `xwagmi-store`) by Zustand's `persist` middleware. On page reload:
|
|
220
|
+
|
|
221
|
+
- **Provider-managed chains** — wagmi/wallet-adapter/dapp-kit auto-reconnect from their own persistence layer; the Hydrator observes and re-writes the store.
|
|
222
|
+
- **Non-provider chains** — `useInitChainServices` calls `reconnectIcon()` / `reconnectInjective()` / `reconnectStellar()` after hydration. ICON, Injective, and Stellar attempt to reconnect to the previously-connected wallet automatically.
|
|
223
|
+
- **Bitcoin** — `BitcoinXConnector.recreateWalletProvider` rebuilds the provider from `window.*` + the persisted `XAccount` (no popup), so signing works after reload without a reconnect call.
|
|
224
|
+
- **NEAR / Stacks** — no auto-reconnect. The user must re-connect manually after a reload.
|
|
225
|
+
- **Cleanup** — connections for chains no longer in `SodaxWalletProvider` config are removed via `cleanupDisabledConnections()` after persist hydration completes.
|
|
226
|
+
|
|
227
|
+
To detect when persisted state is ready (avoid disconnect flash on first paint), use [`useConnectedChains`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CHAIN_DETECTION.md) and gate UI on `status === 'ready'`.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Error handling
|
|
232
|
+
|
|
233
|
+
`useXConnect` errors fall into two categories:
|
|
234
|
+
|
|
235
|
+
**Configuration errors** — chain type isn't enabled. Message: `Chain "<X>" is not enabled or ChainActions not registered`. Fix by adding the slot to `SodaxWalletProvider` config.
|
|
236
|
+
|
|
237
|
+
**Wallet/runtime errors** — propagated from the underlying wallet SDK. Examples:
|
|
238
|
+
|
|
239
|
+
| Source | Message style |
|
|
240
|
+
|--------|---------------|
|
|
241
|
+
| User rejects in wallet popup | Wallet-specific (`"User rejected the request"`, `"User denied account authorization"`, etc.) |
|
|
242
|
+
| Wallet not installed | `"Wallet extension not detected"` (varies by chain) |
|
|
243
|
+
| Network mismatch | `"Chain not configured"` (wagmi) |
|
|
244
|
+
|
|
245
|
+
Read `mutation.error.message` and surface to UI; for install CTA, fall back to `connector.installUrl`:
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
const { mutateAsync: connect, error } = useXConnect();
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<>
|
|
252
|
+
<button onClick={() => connect(connector).catch(() => {})}>Connect</button>
|
|
253
|
+
{error && (
|
|
254
|
+
<div>
|
|
255
|
+
{error.message}
|
|
256
|
+
{!connector.isInstalled && connector.installUrl && (
|
|
257
|
+
<a href={connector.installUrl}>Install {connector.name}</a>
|
|
258
|
+
)}
|
|
259
|
+
</div>
|
|
260
|
+
)}
|
|
261
|
+
</>
|
|
262
|
+
);
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
For multi-chain modal flows that wrap connect with status + retry semantics, see [`WALLET_MODAL.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/WALLET_MODAL.md).
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Related docs
|
|
270
|
+
|
|
271
|
+
- [Configure SodaxWalletProvider](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONFIGURE_PROVIDER.md) — chain-type slots, opt-in mounting
|
|
272
|
+
- [Wallet Provider Bridge](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/WALLET_PROVIDER_BRIDGE.md) — `useWalletProvider` → typed `IXxxWalletProvider` for SDK calls
|
|
273
|
+
- [Wallet Modal](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/WALLET_MODAL.md) — headless state machine (chainSelect → walletSelect → connecting → success | error)
|
|
274
|
+
- [Chain Detection](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CHAIN_DETECTION.md) — aggregate connected-chain views + hydration status
|
|
275
|
+
- [EVM Switch Chain](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/EVM_SWITCH_CHAIN.md) — single wagmi connection across EVM networks
|
|
276
|
+
- [Connectors](https://github.com/icon-project/sodax-sdks/blob/main/packages/wallet-sdk-react/docs/CONNECTORS.md) — `IXConnector` contract, deep imports for concrete classes
|