@sodax/wallet-sdk-core 1.5.7-beta → 2.0.0-rc.2

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.
Files changed (53) hide show
  1. package/README.md +231 -1
  2. package/ai-exported/AGENTS.md +139 -0
  3. package/ai-exported/integration/README.md +108 -0
  4. package/ai-exported/integration/ai-rules.md +141 -0
  5. package/ai-exported/integration/architecture.md +212 -0
  6. package/ai-exported/integration/features/README.md +22 -0
  7. package/ai-exported/integration/features/bitcoin.md +103 -0
  8. package/ai-exported/integration/features/evm.md +102 -0
  9. package/ai-exported/integration/features/icon.md +88 -0
  10. package/ai-exported/integration/features/injective.md +92 -0
  11. package/ai-exported/integration/features/near.md +92 -0
  12. package/ai-exported/integration/features/solana.md +104 -0
  13. package/ai-exported/integration/features/stacks.md +91 -0
  14. package/ai-exported/integration/features/stellar.md +95 -0
  15. package/ai-exported/integration/features/sui.md +96 -0
  16. package/ai-exported/integration/quickstart.md +259 -0
  17. package/ai-exported/integration/recipes/README.md +15 -0
  18. package/ai-exported/integration/recipes/bridge-to-sdk.md +145 -0
  19. package/ai-exported/integration/recipes/defaults-and-overrides.md +159 -0
  20. package/ai-exported/integration/recipes/library-exports.md +129 -0
  21. package/ai-exported/integration/recipes/setup-browser-extension.md +137 -0
  22. package/ai-exported/integration/recipes/setup-private-key.md +115 -0
  23. package/ai-exported/integration/recipes/sign-and-broadcast.md +201 -0
  24. package/ai-exported/integration/recipes/testing.md +163 -0
  25. package/ai-exported/integration/reference/README.md +13 -0
  26. package/ai-exported/integration/reference/chain-support.md +65 -0
  27. package/ai-exported/integration/reference/glossary.md +28 -0
  28. package/ai-exported/integration/reference/interfaces.md +131 -0
  29. package/ai-exported/integration/reference/provider-classes.md +54 -0
  30. package/ai-exported/integration/reference/public-api.md +128 -0
  31. package/ai-exported/migration/README.md +84 -0
  32. package/ai-exported/migration/ai-rules.md +139 -0
  33. package/ai-exported/migration/breaking-changes/README.md +14 -0
  34. package/ai-exported/migration/breaking-changes/base-wallet-provider.md +52 -0
  35. package/ai-exported/migration/breaking-changes/defaults-config.md +57 -0
  36. package/ai-exported/migration/breaking-changes/folder-layout.md +99 -0
  37. package/ai-exported/migration/breaking-changes/library-exports.md +58 -0
  38. package/ai-exported/migration/checklist.md +62 -0
  39. package/ai-exported/migration/recipes/README.md +12 -0
  40. package/ai-exported/migration/recipes/adopt-defaults.md +84 -0
  41. package/ai-exported/migration/recipes/adopt-library-exports.md +99 -0
  42. package/ai-exported/migration/reference/README.md +12 -0
  43. package/ai-exported/migration/reference/added-fields.md +71 -0
  44. package/ai-exported/migration/reference/deleted-exports.md +35 -0
  45. package/ai-exported/migration/reference/renamed-symbols.md +31 -0
  46. package/ai-exported/migration/reference/return-shapes.md +23 -0
  47. package/dist/index.cjs +3200 -2392
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +415 -128
  50. package/dist/index.d.ts +415 -128
  51. package/dist/index.mjs +3197 -2395
  52. package/dist/index.mjs.map +1 -1
  53. package/package.json +10 -8
package/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  The Sodax wallet-sdk-core is a core wallet SDK package containing implementations of wallet providers that enable multi-chain wallet connectivity. This package provides TypeScript implementations of wallet providers for various blockchain networks, making them compatible with the Core Sodax SDK (@sodax/sdk).
4
4
 
5
+ > **AI-friendly docs:** see [`ai-exported/AGENTS.md`](./ai-exported/AGENTS.md) for the agent-readable integration & migration guide.
6
+ > Entry points: [`ai-exported/integration/`](./ai-exported/integration/) (new setup), [`ai-exported/migration/`](./ai-exported/migration/) (upgrading from older RCs).
7
+
5
8
  ## Installation
6
9
 
7
10
  ```bash
@@ -33,4 +36,231 @@ The package includes wallet provider implementations for:
33
36
  - Injective ✅
34
37
  - Near ✅
35
38
  - Stacks ✅
36
- - Bitcoin ✅
39
+ - Bitcoin ✅
40
+
41
+ ## Public API surface
42
+
43
+ The package root exports:
44
+
45
+ - Wallet providers from `src/wallet-providers/*` (e.g. `EvmWalletProvider`, `SolanaWalletProvider`, `BitcoinWalletProvider`)
46
+ - `library-exports` from `src/types/library-exports.ts` (types and a few runtime values re-exported from upstream chain SDKs)
47
+
48
+ Internal utilities (e.g. `shallowMerge` in `src/utils/merge.ts`) are **not** exported from the package root.
49
+
50
+ ## Config variants (private key vs browser/extension)
51
+
52
+ All providers support two modes, but **the union discriminant depends on the provider**:
53
+
54
+ - **Field presence (no `type` field in config)**: EVM, Solana, Sui, Near, Stacks, Icon, Injective
55
+ - **Explicit uppercase `type` field**: Bitcoin, Stellar (`'PRIVATE_KEY' | 'BROWSER_EXTENSION'`)
56
+
57
+ ### EVM
58
+
59
+ ```ts
60
+ import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
61
+ import { ChainKeys } from '@sodax/types';
62
+
63
+ // Private key (Node/scripts/CI)
64
+ const evmPk = new EvmWalletProvider({
65
+ privateKey: '0x...',
66
+ chainId: ChainKeys.SONIC_MAINNET,
67
+ rpcUrl: 'https://...',
68
+ defaults: {
69
+ sendTransaction: { gas: 3_000_000n },
70
+ },
71
+ });
72
+
73
+ // Browser/extension (consumer supplies viem clients)
74
+ const evmBrowser = new EvmWalletProvider({
75
+ walletClient: myViemWalletClient,
76
+ publicClient: myViemPublicClient,
77
+ });
78
+ ```
79
+
80
+ ### Solana
81
+
82
+ ```ts
83
+ import { SolanaWalletProvider } from '@sodax/wallet-sdk-core';
84
+
85
+ const solanaPk = new SolanaWalletProvider({
86
+ privateKey: new Uint8Array([]),
87
+ endpoint: 'https://api.mainnet-beta.solana.com',
88
+ });
89
+
90
+ const solanaBrowser = new SolanaWalletProvider({
91
+ wallet: {
92
+ publicKey: myPublicKeyOrNull,
93
+ signTransaction: mySignTransactionOrUndefined,
94
+ },
95
+ endpoint: 'https://api.mainnet-beta.solana.com',
96
+ });
97
+ ```
98
+
99
+ ### Bitcoin
100
+
101
+ ```ts
102
+ import { BitcoinWalletProvider } from '@sodax/wallet-sdk-core';
103
+
104
+ const btcPk = new BitcoinWalletProvider({
105
+ type: 'PRIVATE_KEY',
106
+ privateKey: '0x...',
107
+ network: 'TESTNET',
108
+ defaults: { defaultFinalize: true },
109
+ });
110
+
111
+ const btcBrowser = new BitcoinWalletProvider({
112
+ type: 'BROWSER_EXTENSION',
113
+ walletsKit: myWalletsKit,
114
+ network: 'TESTNET',
115
+ });
116
+ ```
117
+
118
+ ### Sui
119
+
120
+ Sui uses `mnemonics` (not `privateKey`) for private-key mode. Browser extension requires a pre-constructed `SuiClient`, wallet object, and active `WalletAccount`.
121
+
122
+ ```ts
123
+ import { SuiWalletProvider } from '@sodax/wallet-sdk-core';
124
+
125
+ // Private key (Node/scripts/CI) — field presence discriminant
126
+ const suiPk = new SuiWalletProvider({
127
+ rpcUrl: 'https://...',
128
+ mnemonics: '...',
129
+ });
130
+
131
+ // Browser/extension
132
+ const suiBrowser = new SuiWalletProvider({
133
+ client: mySuiClient,
134
+ wallet: myWalletWithFeatures,
135
+ account: myWalletAccount,
136
+ });
137
+ ```
138
+
139
+ ### Stellar
140
+
141
+ Stellar uses an explicit uppercase `type` field (`'PRIVATE_KEY' | 'BROWSER_EXTENSION'`).
142
+
143
+ ```ts
144
+ import { StellarWalletProvider } from '@sodax/wallet-sdk-core';
145
+
146
+ // Private key (Node/scripts/CI)
147
+ const stellarPk = new StellarWalletProvider({
148
+ type: 'PRIVATE_KEY',
149
+ privateKey: '0x...',
150
+ network: 'PUBLIC',
151
+ rpcUrl: 'https://...',
152
+ });
153
+
154
+ // Browser/extension
155
+ const stellarBrowser = new StellarWalletProvider({
156
+ type: 'BROWSER_EXTENSION',
157
+ walletsKit: myStellarWalletsKit,
158
+ network: 'PUBLIC',
159
+ });
160
+ ```
161
+
162
+ ### Stacks
163
+
164
+ Stacks discriminates by field presence (no `type` field). The private-key config has `privateKey`; the browser-extension config has `address` (and optionally a `StacksProvider`).
165
+
166
+ ```ts
167
+ import { StacksWalletProvider } from '@sodax/wallet-sdk-core';
168
+
169
+ // Private key (Node/scripts/CI)
170
+ const stacksPk = new StacksWalletProvider({
171
+ privateKey: '...',
172
+ endpoint: 'https://...',
173
+ });
174
+
175
+ // Browser/extension
176
+ const stacksBrowser = new StacksWalletProvider({
177
+ address: 'SP...',
178
+ endpoint: 'https://...',
179
+ provider: myStacksProvider,
180
+ });
181
+ ```
182
+
183
+ ### ICON
184
+
185
+ ICON discriminates by field presence. The browser-extension config uses an optional `walletAddress` field (not a client object); `rpcUrl` is required in both modes.
186
+
187
+ ```ts
188
+ import { IconWalletProvider } from '@sodax/wallet-sdk-core';
189
+
190
+ // Private key (Node/scripts/CI)
191
+ const iconPk = new IconWalletProvider({
192
+ privateKey: '0x...',
193
+ rpcUrl: 'https://...',
194
+ });
195
+
196
+ // Browser/extension (Hana wallet)
197
+ const iconBrowser = new IconWalletProvider({
198
+ walletAddress: 'hx...',
199
+ rpcUrl: 'https://...',
200
+ });
201
+ ```
202
+
203
+ ### Injective
204
+
205
+ Injective discriminates by field presence. The private-key config uses a nested `secret` object that accepts either `{ privateKey }` or `{ mnemonics }` — it is named `SecretInjectiveWalletConfig` rather than `PrivateKey*` to reflect this dual credential shape.
206
+
207
+ ```ts
208
+ import { InjectiveWalletProvider } from '@sodax/wallet-sdk-core';
209
+
210
+ // Private key path — via secret credential
211
+ const injectivePk = new InjectiveWalletProvider({
212
+ secret: { privateKey: '...' },
213
+ chainId: myChainId,
214
+ network: myNetwork,
215
+ });
216
+
217
+ // Mnemonics path — same config shape, different secret variant
218
+ const injectiveMnemonic = new InjectiveWalletProvider({
219
+ secret: { mnemonics: '...' },
220
+ chainId: myChainId,
221
+ network: myNetwork,
222
+ });
223
+
224
+ // Browser/extension
225
+ const injectiveBrowser = new InjectiveWalletProvider({
226
+ msgBroadcaster: myMsgBroadcaster,
227
+ });
228
+ ```
229
+
230
+ ### NEAR
231
+
232
+ NEAR discriminates by field presence. The private-key config requires `rpcUrl`, `accountId`, and `privateKey`; the browser-extension config wraps a `NearConnector`.
233
+
234
+ ```ts
235
+ import { NearWalletProvider } from '@sodax/wallet-sdk-core';
236
+
237
+ // Private key (Node/scripts/CI)
238
+ const nearPk = new NearWalletProvider({
239
+ rpcUrl: 'https://...',
240
+ accountId: '...',
241
+ privateKey: '...',
242
+ });
243
+
244
+ // Browser/extension
245
+ const nearBrowser = new NearWalletProvider({
246
+ wallet: myNearConnector,
247
+ });
248
+ ```
249
+
250
+ ## Defaults and merge semantics
251
+
252
+ Each provider accepts optional `defaults`, and most methods accept per-call options. The SDK combines layers using a **shallow merge**:
253
+
254
+ - Only top-level keys are merged; **nested objects are replaced**, not deep-merged.
255
+ - `undefined` layers are skipped.
256
+ - `undefined` values inside a layer are skipped (so `{ field: undefined }` means “don’t override the previous layer”).
257
+
258
+ ## `library-exports`
259
+
260
+ `library-exports` re-exports types (and a few runtime values) from underlying chain SDKs so consumers can reduce direct dependencies.
261
+
262
+ Example:
263
+
264
+ ```ts
265
+ import type { WalletClient, PublicClient } from '@sodax/wallet-sdk-core';
266
+ ```
@@ -0,0 +1,139 @@
1
+ # AGENTS.md — `@sodax/wallet-sdk-core` AI Export
2
+
3
+ You are a coding agent helping a developer **integrate** or **migrate** the `@sodax/wallet-sdk-core` package. This document is your entry point. Read this first, then route to the right sub-folder.
4
+
5
+ The files in this `ai-exported/` directory are designed for AI consumption: short, table-heavy, self-contained recipes, and machine-checkable checklists. Human-readable narrative lives in each folder's `README.md`.
6
+
7
+ ---
8
+
9
+ ## What this package is
10
+
11
+ `@sodax/wallet-sdk-core` is the **low-level** wallet layer of the SODAX stack — one provider class per chain family (9 in total: EVM, Solana, Sui, Bitcoin, Stellar, ICON, Injective, NEAR, Stacks). Each class accepts either a **private-key** config (server-side scripts, CI, Node) or a **browser-extension** config (consumer dApps with pre-built clients/wallet kits), signs transactions, and broadcasts them.
12
+
13
+ It is **not** a React layer (that is `@sodax/wallet-sdk-react`) and **not** a hooks layer (that is `@sodax/dapp-kit`). Most React consumers never touch this package directly — they get a typed `IXxxWalletProvider` via `useWalletProvider(...)` and hand it to `@sodax/sdk` calls. Direct usage of `wallet-sdk-core` is the right choice for:
14
+
15
+ - Backend / Node scripts (CI tests, indexers, bots).
16
+ - Custom browser flows that don't use React.
17
+ - Tests that need to sign with a deterministic key.
18
+
19
+ ---
20
+
21
+ ## Step 1 — Identify the task
22
+
23
+ | User says... | Path | Start at |
24
+ |---|---|---|
25
+ | "sign a tx from a script", "instantiate `EvmWalletProvider`", "first time using this lib" | **integration** | `integration/ai-rules.md` |
26
+ | "configure default gas", "set up `defaults`", "shallow merge surprised me" | **integration** | `integration/recipes/defaults-and-overrides.md` |
27
+ | "where do I import `WalletClient` / `SuiClient` from", "avoid direct viem dep" | **integration** | `integration/recipes/library-exports.md` |
28
+ | "upgrade from v1 / sodax-frontend", "bump from older RC" | **migration** | `migration/ai-rules.md` |
29
+ | Deep import from `@sodax/wallet-sdk-core/wallet-providers/EvmWalletProvider` broke | **migration** | `migration/breaking-changes/folder-layout.md` |
30
+ | Looking up a provider class or its config shape | direct | `integration/reference/provider-classes.md` |
31
+ | Looking up the discriminated union shape per chain | direct | `integration/features/<chain>.md` |
32
+
33
+ The package name **did not change** across versions — both v1 and v2 publish as `@sodax/wallet-sdk-core`. **All v1→v2 surface changes are additive** — class names, config-type names, and config shapes are identical. The only mechanical migration is replacing deep imports from v1's flat `wallet-providers/*.ts` layout with barrel imports.
34
+
35
+ If a project does anything more than that at the wallet-sdk-core surface, you are almost certainly looking at an `@sodax/sdk` / `@sodax/types` migration, not this one. Route accordingly.
36
+
37
+ ---
38
+
39
+ ## Step 2 — Load the right context
40
+
41
+ **For integration tasks:**
42
+
43
+ 1. `integration/ai-rules.md` — DO/DON'T + workflow + stop conditions
44
+ 2. `integration/architecture.md` — mental model (BaseWalletProvider, discriminants, defaults merge)
45
+ 3. `integration/quickstart.md` — copy-paste minimal example for the chain you need
46
+ 4. `integration/features/<chain>.md` — per-chain config table, methods, gotchas
47
+ 5. `integration/recipes/<task>.md` — task-specific guide (setup-private-key, bridge-to-sdk, …)
48
+ 6. `integration/reference/*.md` — full barrel exports, interfaces, chain support
49
+
50
+ **For migration tasks:**
51
+
52
+ 1. `migration/ai-rules.md` — DO/DON'T + workflow. The headline: **v1 code drops in unchanged.** No mandatory edits at the wallet-sdk-core surface.
53
+ 2. `migration/README.md` — what (additively) changed, read order, TL;DR
54
+ 3. `migration/breaking-changes/*.md` — narrative WHY behind each additive shift (folder layout, base-class, defaults, library-exports)
55
+ 4. `migration/reference/*.md` — confirm no renames / no deletions exist
56
+ 5. `migration/recipes/<task>.md` — paired before/after for **optional** cleanup (adopt-defaults, adopt-library-exports)
57
+ 6. `migration/checklist.md` — verification loop
58
+
59
+ ---
60
+
61
+ ## Step 3 — Honor flow-specific stop conditions
62
+
63
+ Each flow has its own list of conditions that **HARD STOP** code generation and require asking the user:
64
+
65
+ - Migration stops → [`migration/ai-rules.md`](./migration/ai-rules.md) § "Stop conditions"
66
+ - Integration stops → [`integration/ai-rules.md`](./integration/ai-rules.md) § "Stop conditions"
67
+
68
+ Read the relevant list **before** applying any change. When stopping, quote the offending file/line and present the user with concrete options. Do **not** guess.
69
+
70
+ Cross-flow signals (true regardless of flow):
71
+
72
+ - User asks for a chain family not in [`integration/reference/chain-support.md`](./integration/reference/chain-support.md). Adding a new chain is a maintainer task, not user-app integration.
73
+ - User wants to extend `BaseWalletProvider` directly. That is a maintainer-only path — confirm scope before writing code.
74
+
75
+ ---
76
+
77
+ ## Step 4 — Verification protocol
78
+
79
+ After **every** code change you make:
80
+
81
+ 1. Run `pnpm checkTs` from the user's app root (or the package the change touched).
82
+ 2. If errors mention `@sodax/wallet-sdk-core`, look up the symbol in `integration/reference/` or `migration/reference/`.
83
+ 3. If a symbol isn't in any reference file, **stop and ask**. Do not invent migrations.
84
+ 4. After all errors resolve, mark the relevant items in `migration/checklist.md` (for migrations) or move to the next recipe.
85
+
86
+ You are **done** when:
87
+ - `pnpm checkTs` exits clean for the user's project.
88
+ - All items in `migration/checklist.md` are checked (migration only).
89
+ - The user has confirmed the changed flow works in their dev / test environment.
90
+
91
+ ---
92
+
93
+ ## Conventions in this directory
94
+
95
+ - **Recipes are self-contained.** A recipe file in `recipes/` contains everything needed to apply the change — before/after code, steps, verification. Do not jump between files.
96
+ - **Reference files are tables.** `reference/*.md` contains markdown tables and paired code blocks. Treat them as lookup, not narrative.
97
+ - **Token budget**: Each file is sized to fit comfortably in your context. If you find yourself loading more than 3 files for a single task, you are probably doing it wrong — re-route via the table above.
98
+ - **Single source of truth**: Behavioral / breaking-change *explanations* live only in `migration/breaking-changes/*.md`. Other files reference them but do not duplicate the prose.
99
+
100
+ ---
101
+
102
+ ## Quick symbol lookup
103
+
104
+ If the user mentions a symbol you don't recognize, grep these files in order:
105
+
106
+ ```
107
+ integration/reference/public-api.md — every named export from the package
108
+ integration/reference/provider-classes.md — provider class + config + interface mapping
109
+ integration/reference/interfaces.md — IXxxWalletProvider method signatures
110
+ integration/reference/chain-support.md — chain family → provider + dependencies
111
+ migration/reference/renamed-symbols.md — confirms zero renames between v1 and v2
112
+ migration/reference/deleted-exports.md — confirms zero deletions between v1 and v2
113
+ migration/reference/added-fields.md — additive `defaults` / `*WalletDefaults` / `*Policy` types
114
+ ```
115
+
116
+ If still not found: the symbol may be **internal** (not exported from the package root) or **removed**. Ask the user to share the source file/line so you can decide.
117
+
118
+ ---
119
+
120
+ ## Package context
121
+
122
+ - **Name**: `@sodax/wallet-sdk-core`
123
+ - **Version target**: latest RC / stable on npm.
124
+ - **Peer deps**: none — chain SDKs are direct dependencies and consumers can re-import types via `library-exports`.
125
+ - **Install**: `pnpm add @sodax/wallet-sdk-core`
126
+ - **Runtime**: Node ≥ 18 + browser (tsup `platform: 'neutral'`).
127
+ - **Audience**: backend engineers, script authors, and React-layer authors building higher-level wrappers (`@sodax/wallet-sdk-react`).
128
+
129
+ ---
130
+
131
+ ## Pointers
132
+
133
+ - [`integration/README.md`](./integration/README.md) — start here for new integrations: file index, recommended reading order, install snippet, dual-config overview.
134
+ - [`migration/README.md`](./migration/README.md) — start here for upgrades: file index, reading order, cross-cutting checklist pointer.
135
+ - [`integration/quickstart.md`](./integration/quickstart.md) — minimal end-to-end example per chain.
136
+ - [`integration/architecture.md`](./integration/architecture.md) — mental model: `BaseWalletProvider`, defaults shallow merge, dual-config discriminants, `library-exports`.
137
+ - [`integration/features/`](./integration/features/) — per-chain config table, methods, gotchas (one file per chain).
138
+ - [`integration/reference/`](./integration/reference/) — public API, provider classes, interfaces, chain support, glossary.
139
+ - [`migration/breaking-changes/`](./migration/breaking-changes/) — narrative WHY behind each version-to-version shift.
@@ -0,0 +1,108 @@
1
+ # Integration: First-time setup (Human-readable overview)
2
+
3
+ This folder helps you integrate `@sodax/wallet-sdk-core` into a fresh project — most commonly a Node script, a backend service, or a custom non-React frontend. It is the **human-facing** entry point for new integrations. If you are a coding agent, read [`ai-rules.md`](./ai-rules.md) first.
4
+
5
+ If you are upgrading from an older version of the package instead, see `../migration/`.
6
+
7
+ ---
8
+
9
+ ## What this package does
10
+
11
+ `@sodax/wallet-sdk-core` is a **low-level multi-chain wallet provider layer**. For each of the 9 chain families that SODAX supports it ships **one provider class** that:
12
+
13
+ - Accepts a **discriminated union config** — `PrivateKey*WalletConfig | BrowserExtension*WalletConfig`.
14
+ - Extends a small `BaseWalletProvider` to merge per-call options over a typed `defaults` shape.
15
+ - Implements the chain-specific `IXxxWalletProvider` interface from `@sodax/types`, so it can be passed straight into `@sodax/sdk` calls.
16
+
17
+ It is intentionally framework-agnostic — Node ≥ 18, browser, edge runtimes are all supported (tsup `platform: 'neutral'`).
18
+
19
+ | Chain family | Provider class | Underlying chain SDK |
20
+ |---|---|---|
21
+ | EVM (12 chains) | `EvmWalletProvider` | `viem` |
22
+ | Solana | `SolanaWalletProvider` | `@solana/web3.js` |
23
+ | Sui | `SuiWalletProvider` | `@mysten/sui` + `@mysten/wallet-standard` |
24
+ | Bitcoin | `BitcoinWalletProvider` | `bitcoinjs-lib` (+ `ecpair`, `secp256k1`) |
25
+ | Stellar | `StellarWalletProvider` | `@stellar/stellar-sdk` |
26
+ | ICON | `IconWalletProvider` | `icon-sdk-js` |
27
+ | Injective | `InjectiveWalletProvider` | `@injectivelabs/sdk-ts` + `@injectivelabs/wallet-core` |
28
+ | NEAR | `NearWalletProvider` | `near-api-js` + `@hot-labs/near-connect` |
29
+ | Stacks | `StacksWalletProvider` | `@stacks/transactions` + `@stacks/connect` |
30
+
31
+ ---
32
+
33
+ ## Recommended path (in order)
34
+
35
+ If this is your first time using the package:
36
+
37
+ 1. [`architecture.md`](./architecture.md) — read once before any recipe. Explains `BaseWalletProvider`, the `defaults` shallow-merge model, dual-config discriminants, and the `library-exports` indirection. Picking the wrong config variant is the most common mistake — the mental model prevents it.
38
+ 2. [`quickstart.md`](./quickstart.md) — minimal end-to-end example for the chain you need. Copy, edit, run.
39
+ 3. [`features/<chain>.md`](./features/) — chain-specific config table, methods, and gotchas (one file per chain).
40
+ 4. Pick the right recipes:
41
+ - [`recipes/setup-private-key.md`](./recipes/setup-private-key.md) — server-side / CI flow.
42
+ - [`recipes/setup-browser-extension.md`](./recipes/setup-browser-extension.md) — consumer dApp flow.
43
+ - [`recipes/bridge-to-sdk.md`](./recipes/bridge-to-sdk.md) — hand off the provider to `@sodax/sdk` calls.
44
+ - [`recipes/defaults-and-overrides.md`](./recipes/defaults-and-overrides.md) — merge semantics for the `defaults` config.
45
+ - [`recipes/library-exports.md`](./recipes/library-exports.md) — re-importing upstream chain-SDK types without a direct dep.
46
+ - [`recipes/sign-and-broadcast.md`](./recipes/sign-and-broadcast.md) — typical send-transaction flow per chain.
47
+ - [`recipes/testing.md`](./recipes/testing.md) — mocking providers in unit tests.
48
+ 5. Reference docs (lookup as needed):
49
+ - [`reference/public-api.md`](./reference/public-api.md) — every named export from the package root.
50
+ - [`reference/provider-classes.md`](./reference/provider-classes.md) — provider × config × interface table.
51
+ - [`reference/interfaces.md`](./reference/interfaces.md) — `IXxxWalletProvider` method signatures.
52
+ - [`reference/chain-support.md`](./reference/chain-support.md) — chain family → spoke chain keys.
53
+ - [`reference/glossary.md`](./reference/glossary.md) — terms used across the docs.
54
+
55
+ ---
56
+
57
+ ## Install
58
+
59
+ ```bash
60
+ pnpm add @sodax/wallet-sdk-core @sodax/types
61
+ ```
62
+
63
+ Most consumers will also need `@sodax/sdk` (for the hub/spoke services that accept the wallet provider) and one or more chain SDKs (for browser-extension wallet objects). Re-export the types you need via `library-exports` — see [`recipes/library-exports.md`](./recipes/library-exports.md).
64
+
65
+ ---
66
+
67
+ ## Two configuration modes
68
+
69
+ Every provider class supports **two** construction modes. Picking the wrong one is the most common integration mistake.
70
+
71
+ | Mode | When to use | Discriminant style |
72
+ |---|---|---|
73
+ | **Private-key** | Node scripts, CI tests, indexers, bots — anywhere you possess the raw key | Either field presence (EVM, Solana, Sui, ICON, Injective, NEAR, Stacks) OR `type: 'PRIVATE_KEY'` (Bitcoin, Stellar) |
74
+ | **Browser-extension** | Consumer dApps where a wallet extension provides a pre-built client / signer | Either field presence (different fields from PK variant) OR `type: 'BROWSER_EXTENSION'` (Bitcoin, Stellar) |
75
+
76
+ For a chain-by-chain breakdown of the exact discriminant shape, see [`features/`](./features/) and [`architecture.md`](./architecture.md) § "Discriminant variants".
77
+
78
+ ---
79
+
80
+ ## Pair with `@sodax/sdk` and `@sodax/wallet-sdk-react`
81
+
82
+ The most common stack:
83
+
84
+ ```
85
+ @sodax/sdk ← business logic (swaps, lending, staking, …)
86
+ @sodax/wallet-sdk-react ← React layer that surfaces a typed IXxxWalletProvider via hooks
87
+ @sodax/wallet-sdk-core ← this package — concrete provider classes
88
+ @sodax/types ← shared type definitions
89
+ ```
90
+
91
+ In a React dApp you usually consume this package **indirectly** — `useWalletProvider({ xChainId })` (from `@sodax/wallet-sdk-react`) returns a typed `IXxxWalletProvider` that comes from a `wallet-sdk-core` instance under the hood. You only construct provider classes from `wallet-sdk-core` directly when running scripts, tests, or non-React clients.
92
+
93
+ ---
94
+
95
+ ## Conventions worth knowing
96
+
97
+ - **`defaults` is optional but powerful.** Every provider accepts a `defaults` config slice; per-call options shallow-merge over it. Use it to encode env-level fixed choices (RPC commitment, default gas, default memo) once.
98
+ - **Shallow merge, not deep.** Nested objects in `defaults` are **replaced wholesale** by per-call options of the same key. See `src/utils/merge.ts` and [`recipes/defaults-and-overrides.md`](./recipes/defaults-and-overrides.md).
99
+ - **`library-exports` removes upstream deps.** You can `import type { WalletClient } from '@sodax/wallet-sdk-core'` instead of taking a direct dep on `viem`. See [`recipes/library-exports.md`](./recipes/library-exports.md).
100
+ - **The barrel is the source of truth.** Internal utilities (`shallowMerge`, helper functions) are **not** exported. If something isn't on `@sodax/wallet-sdk-core`'s root, do not deep-import it.
101
+ - **No `as unknown as` casts.** The discriminated unions are precise — if TypeScript complains, your config is wrong, not the type.
102
+
103
+ ---
104
+
105
+ ## Getting help
106
+
107
+ - API surface lookup: [`reference/`](./reference/).
108
+ - Bug or missing feature: [open an issue](https://github.com/icon-project/sodax-sdks/issues).
@@ -0,0 +1,141 @@
1
+ # AI Rules — Fresh Integration
2
+
3
+ You are integrating `@sodax/wallet-sdk-core` into a user's project for the first time. Follow this protocol exactly.
4
+
5
+ ---
6
+
7
+ ## Workflow (do these in order)
8
+
9
+ ### 1. Survey the project
10
+
11
+ Before changing anything, gather context:
12
+
13
+ ```bash
14
+ # Runtime — Node script? React dApp? Edge runtime?
15
+ cat <user>/package.json | grep -E '"type|"main|"module'
16
+
17
+ # Node version — must be >= 18
18
+ cat <user>/.nvmrc 2>/dev/null
19
+ node --version
20
+
21
+ # Is the user already using @sodax/wallet-sdk-react?
22
+ cat <user>/package.json | grep '"@sodax/wallet-sdk-react'
23
+
24
+ # Are upstream chain SDKs already direct deps? (may indicate they don't yet know about library-exports)
25
+ cat <user>/package.json | grep -E '"viem"|"@solana/web3.js"|"@mysten/sui"|"@stellar/stellar-sdk"|"@stacks/transactions"|"@injectivelabs"|"near-api-js"|"bitcoinjs-lib"|"icon-sdk-js"'
26
+ ```
27
+
28
+ **If Node < 18**, stop and tell the user — this package requires Node ≥ 18.
29
+
30
+ **If the user is already using `@sodax/wallet-sdk-react` in the same project**, ask whether they really need to construct providers directly. In a React app the answer is usually **no**: `useWalletProvider({ xChainId })` returns the typed provider for them. Direct construction is only correct for scripts, tests, or non-React clients.
31
+
32
+ ### 2. Pick the right mode
33
+
34
+ For **each** chain the user wants to integrate, decide between:
35
+
36
+ | Mode | When to pick | Stop and ask if... |
37
+ |---|---|---|
38
+ | **Private-key** | A Node script, CI runner, indexer, or test that legitimately possesses a raw key. | The user pastes a real-looking key in a frontend file. Never embed a private key in a browser bundle. |
39
+ | **Browser-extension** | A dApp where a wallet extension (MetaMask, Phantom, Xverse, Hana, Freighter, Leather, …) provides the signing primitives. | The user has neither a key nor a wallet adapter on hand. They probably want `@sodax/wallet-sdk-react` instead. |
40
+
41
+ Ask the user which mode applies **before** writing code. Default to **private-key** for `apps/node`-style scripts and **browser-extension** for `apps/web`-style dApps.
42
+
43
+ ### 3. Apply the matching recipe
44
+
45
+ - Private-key flow → [`recipes/setup-private-key.md`](./recipes/setup-private-key.md).
46
+ - Browser-extension flow → [`recipes/setup-browser-extension.md`](./recipes/setup-browser-extension.md).
47
+
48
+ Each recipe is self-contained — install snippet, config, first method call, verification.
49
+
50
+ ### 4. Hand off to `@sodax/sdk` if needed
51
+
52
+ If the user wants to swap / bridge / stake / lend / migrate, they need to pass the provider to `@sodax/sdk` calls. Apply [`recipes/bridge-to-sdk.md`](./recipes/bridge-to-sdk.md). Do not invent your own bridging pattern.
53
+
54
+ ### 5. Add advanced features as separate steps
55
+
56
+ Only after the basic flow works should you add:
57
+
58
+ - Default config slices ([`recipes/defaults-and-overrides.md`](./recipes/defaults-and-overrides.md))
59
+ - Importing upstream chain types via `library-exports` ([`recipes/library-exports.md`](./recipes/library-exports.md))
60
+ - Sign + broadcast flow for the chain ([`recipes/sign-and-broadcast.md`](./recipes/sign-and-broadcast.md))
61
+ - Mocking providers in tests ([`recipes/testing.md`](./recipes/testing.md))
62
+
63
+ Each is independent — apply only what the user asked for.
64
+
65
+ ---
66
+
67
+ ## DO
68
+
69
+ - **DO** use the discriminated union types in your `import` statement so TypeScript narrows the config correctly:
70
+ ```ts
71
+ import { EvmWalletProvider, type EvmWalletConfig } from '@sodax/wallet-sdk-core';
72
+ ```
73
+ - **DO** use chain key constants from `@sodax/types` (`ChainKeys.SONIC_MAINNET`, `ChainKeys.BSC_MAINNET`, …) instead of magic numbers / strings.
74
+ - **DO** re-export upstream chain types via `library-exports` (`import type { WalletClient } from '@sodax/wallet-sdk-core'`) — keeps direct chain-SDK deps out of `package.json`.
75
+ - **DO** pass an `IXxxWalletProvider` (the **interface** from `@sodax/types`), not the concrete class, to SDK calls. Interfaces are how the SDK stays decoupled from this package.
76
+ - **DO** put RPC URLs, network selectors, default gas, etc. in the `defaults` config slice — one place, one source of truth.
77
+ - **DO** consult [`features/<chain>.md`](./features/) for the chain you are integrating before writing the constructor call. Each chain has slightly different field names.
78
+
79
+ ---
80
+
81
+ ## DO NOT
82
+
83
+ - **DO NOT** embed a private key in a frontend bundle. Browser-extension config exists for a reason.
84
+ - **DO NOT** import from `@sodax/wallet-sdk-core/src/...` deep paths. Only the package root is public.
85
+ - **DO NOT** deep-import the internal `shallowMerge` from `src/utils/merge.ts`. It is intentionally not exported.
86
+ - **DO NOT** extend `BaseWalletProvider` in user code unless you are adding a brand-new chain to this package. That is a maintainer-only path.
87
+ - **DO NOT** widen the discriminated union with a cast (e.g. `as EvmWalletConfig`). If TypeScript complains, your fields are wrong — fix the fields.
88
+ - **DO NOT** mutate `defaults` after construction. Providers freeze the `defaults` reference; later mutations are silently ignored.
89
+ - **DO NOT** mix discriminant styles for a chain. Bitcoin and Stellar **require** an uppercase `type: 'PRIVATE_KEY' | 'BROWSER_EXTENSION'`; every other chain uses **field presence**. See [`architecture.md`](./architecture.md) § "Discriminant variants".
90
+
91
+ ---
92
+
93
+ ## Stop conditions (defer to user)
94
+
95
+ | Signal | Why stop |
96
+ |---|---|
97
+ | User asks for a chain family not in [chain support](./reference/chain-support.md) | Adding a new chain is a maintainer task, not user-app integration. |
98
+ | User wants to extend `BaseWalletProvider` directly | Maintainer-only path. Confirm scope first. |
99
+ | User wants to deep-merge `defaults` with per-call options | Not supported — merge is **shallow** by design. See [`recipes/defaults-and-overrides.md`](./recipes/defaults-and-overrides.md). If the user really needs deep merge, they must combine before passing. |
100
+ | User wants to inject a custom `Transport` / `Connection` / `SuiClient` in private-key mode | Some chains expose this via `defaults`; others don't. Check the chain's [feature file](./features/) first. |
101
+ | User wants to use a wallet brand the chain SDK does not support | Out of scope — wallet brand support lives in the upstream chain SDK / kit. |
102
+ | User is in a React app and wants to construct providers in components | Almost always wrong. Direct user to `@sodax/wallet-sdk-react`'s `useWalletProvider` hook. |
103
+ | User asks "how do I sign with X without a key and without an extension" | They probably want a custom signer — this package does not currently model that. Flag as out of scope. |
104
+
105
+ When stopping, **quote the file/line** of the offending code and present the user with concrete options.
106
+
107
+ ---
108
+
109
+ ## Verification protocol (after every recipe)
110
+
111
+ ```bash
112
+ # 1. Type check passes
113
+ pnpm checkTs
114
+
115
+ # 2. No deep imports
116
+ grep -rn "@sodax/wallet-sdk-core/" <user-src> | grep -v "from '@sodax/wallet-sdk-core'"
117
+ # expect empty — only barrel imports allowed
118
+
119
+ # 3. No direct upstream chain-SDK imports for types that library-exports provides
120
+ grep -rn "from 'viem'" <user-src> | grep -E "WalletClient|PublicClient|TransactionReceipt"
121
+ # if any match, suggest re-importing via @sodax/wallet-sdk-core
122
+
123
+ # 4. Sample call works
124
+ # (manual — run a one-shot sign + broadcast on testnet)
125
+ ```
126
+
127
+ If steps 1–3 pass and the user confirms step 4, the recipe is done.
128
+
129
+ ---
130
+
131
+ ## Done criteria
132
+
133
+ The integration is complete when:
134
+
135
+ - [ ] `pnpm checkTs` exits clean.
136
+ - [ ] The user has at least one provider instance constructed via the correct discriminated union variant.
137
+ - [ ] Types are imported from `@sodax/wallet-sdk-core` (and `@sodax/types`) only — no deep paths.
138
+ - [ ] If using `@sodax/sdk`: the provider is passed via the `IXxxWalletProvider` interface, not the concrete class.
139
+ - [ ] A sign + broadcast (or get-address) call has succeeded against testnet or a local mock.
140
+
141
+ Do not declare integration done before all of the above are true.