@sodax/skills 2.0.0-rc.4
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/.claude-plugin/plugin.json +13 -0
- package/AGENTS.md +81 -0
- package/LICENSE +21 -0
- package/README.md +49 -0
- package/knowledge/dapp-kit/AGENTS.md +50 -0
- package/knowledge/dapp-kit/integration/README.md +49 -0
- package/knowledge/dapp-kit/integration/ai-rules.md +80 -0
- package/knowledge/dapp-kit/integration/architecture.md +276 -0
- package/knowledge/dapp-kit/integration/features/README.md +29 -0
- package/knowledge/dapp-kit/integration/features/auxiliary-services.md +169 -0
- package/knowledge/dapp-kit/integration/features/bitcoin.md +87 -0
- package/knowledge/dapp-kit/integration/features/bridge.md +91 -0
- package/knowledge/dapp-kit/integration/features/dex.md +152 -0
- package/knowledge/dapp-kit/integration/features/migration.md +118 -0
- package/knowledge/dapp-kit/integration/features/money-market.md +144 -0
- package/knowledge/dapp-kit/integration/features/staking.md +123 -0
- package/knowledge/dapp-kit/integration/features/swap.md +101 -0
- package/knowledge/dapp-kit/integration/quickstart.md +188 -0
- package/knowledge/dapp-kit/integration/recipes/README.md +136 -0
- package/knowledge/dapp-kit/integration/recipes/backend-queries.md +157 -0
- package/knowledge/dapp-kit/integration/recipes/bitcoin.md +193 -0
- package/knowledge/dapp-kit/integration/recipes/bridge.md +174 -0
- package/knowledge/dapp-kit/integration/recipes/dex.md +204 -0
- package/knowledge/dapp-kit/integration/recipes/invalidations.md +115 -0
- package/knowledge/dapp-kit/integration/recipes/migration.md +212 -0
- package/knowledge/dapp-kit/integration/recipes/money-market.md +207 -0
- package/knowledge/dapp-kit/integration/recipes/mutation-error-handling.md +118 -0
- package/knowledge/dapp-kit/integration/recipes/observability.md +93 -0
- package/knowledge/dapp-kit/integration/recipes/setup.md +168 -0
- package/knowledge/dapp-kit/integration/recipes/staking.md +202 -0
- package/knowledge/dapp-kit/integration/recipes/swap.md +272 -0
- package/knowledge/dapp-kit/integration/recipes/wallet-connectivity.md +128 -0
- package/knowledge/dapp-kit/integration/reference/README.md +12 -0
- package/knowledge/dapp-kit/integration/reference/glossary.md +190 -0
- package/knowledge/dapp-kit/integration/reference/hooks-index.md +190 -0
- package/knowledge/dapp-kit/integration/reference/public-api.md +110 -0
- package/knowledge/dapp-kit/integration/reference/querykey-conventions.md +179 -0
- package/knowledge/dapp-kit/migration/README.md +60 -0
- package/knowledge/dapp-kit/migration/ai-rules.md +81 -0
- package/knowledge/dapp-kit/migration/breaking-changes/hook-signatures.md +233 -0
- package/knowledge/dapp-kit/migration/breaking-changes/querykey-conventions.md +108 -0
- package/knowledge/dapp-kit/migration/breaking-changes/result-handling.md +211 -0
- package/knowledge/dapp-kit/migration/breaking-changes/sdk-leakage.md +167 -0
- package/knowledge/dapp-kit/migration/checklist.md +89 -0
- package/knowledge/dapp-kit/migration/features/README.md +34 -0
- package/knowledge/dapp-kit/migration/features/auxiliary-services.md +114 -0
- package/knowledge/dapp-kit/migration/features/bitcoin.md +88 -0
- package/knowledge/dapp-kit/migration/features/bridge.md +160 -0
- package/knowledge/dapp-kit/migration/features/dex.md +101 -0
- package/knowledge/dapp-kit/migration/features/migration.md +120 -0
- package/knowledge/dapp-kit/migration/features/money-market.md +139 -0
- package/knowledge/dapp-kit/migration/features/staking.md +109 -0
- package/knowledge/dapp-kit/migration/features/swap.md +133 -0
- package/knowledge/dapp-kit/migration/recipes.md +185 -0
- package/knowledge/dapp-kit/migration/reference/README.md +15 -0
- package/knowledge/dapp-kit/migration/reference/deleted-hooks.md +110 -0
- package/knowledge/dapp-kit/migration/reference/error-shape-crosswalk.md +144 -0
- package/knowledge/dapp-kit/migration/reference/renamed-hooks.md +68 -0
- package/knowledge/sdk/AGENTS.md +41 -0
- package/knowledge/sdk/integration/README.md +41 -0
- package/knowledge/sdk/integration/ai-rules.md +75 -0
- package/knowledge/sdk/integration/architecture.md +533 -0
- package/knowledge/sdk/integration/chain-specifics.md +189 -0
- package/knowledge/sdk/integration/features/README.md +19 -0
- package/knowledge/sdk/integration/features/auxiliary-services.md +189 -0
- package/knowledge/sdk/integration/features/bridge.md +136 -0
- package/knowledge/sdk/integration/features/dex.md +182 -0
- package/knowledge/sdk/integration/features/icx-bnusd-baln.md +181 -0
- package/knowledge/sdk/integration/features/money-market.md +198 -0
- package/knowledge/sdk/integration/features/staking.md +166 -0
- package/knowledge/sdk/integration/features/swap.md +207 -0
- package/knowledge/sdk/integration/quickstart.md +213 -0
- package/knowledge/sdk/integration/recipes/README.md +21 -0
- package/knowledge/sdk/integration/recipes/backend-server-init.md +69 -0
- package/knowledge/sdk/integration/recipes/chain-key-narrowing.md +65 -0
- package/knowledge/sdk/integration/recipes/gas-estimation.md +33 -0
- package/knowledge/sdk/integration/recipes/initialize-sodax.md +78 -0
- package/knowledge/sdk/integration/recipes/raw-tx-flow.md +71 -0
- package/knowledge/sdk/integration/recipes/result-and-errors.md +104 -0
- package/knowledge/sdk/integration/recipes/signed-tx-flow.md +46 -0
- package/knowledge/sdk/integration/recipes/testing.md +101 -0
- package/knowledge/sdk/integration/reference/README.md +18 -0
- package/knowledge/sdk/integration/reference/chain-keys.md +67 -0
- package/knowledge/sdk/integration/reference/error-codes.md +165 -0
- package/knowledge/sdk/integration/reference/glossary.md +32 -0
- package/knowledge/sdk/integration/reference/public-api.md +138 -0
- package/knowledge/sdk/integration/reference/wallet-providers.md +62 -0
- package/knowledge/sdk/migration/README.md +58 -0
- package/knowledge/sdk/migration/ai-rules.md +80 -0
- package/knowledge/sdk/migration/breaking-changes/architecture.md +344 -0
- package/knowledge/sdk/migration/breaking-changes/result-and-errors.md +363 -0
- package/knowledge/sdk/migration/breaking-changes/type-system.md +341 -0
- package/knowledge/sdk/migration/checklist.md +67 -0
- package/knowledge/sdk/migration/features/README.md +35 -0
- package/knowledge/sdk/migration/features/auxiliary-services.md +156 -0
- package/knowledge/sdk/migration/features/bridge.md +128 -0
- package/knowledge/sdk/migration/features/dex.md +143 -0
- package/knowledge/sdk/migration/features/icx-bnusd-baln.md +151 -0
- package/knowledge/sdk/migration/features/money-market.md +214 -0
- package/knowledge/sdk/migration/features/staking.md +138 -0
- package/knowledge/sdk/migration/features/swap.md +198 -0
- package/knowledge/sdk/migration/recipes.md +350 -0
- package/knowledge/sdk/migration/reference/README.md +18 -0
- package/knowledge/sdk/migration/reference/deleted-exports.md +127 -0
- package/knowledge/sdk/migration/reference/error-code-crosswalk.md +104 -0
- package/knowledge/sdk/migration/reference/return-shapes.md +49 -0
- package/knowledge/sdk/migration/reference/sodax-config.md +145 -0
- package/knowledge/wallet-sdk-core/AGENTS.md +43 -0
- package/knowledge/wallet-sdk-core/integration/README.md +108 -0
- package/knowledge/wallet-sdk-core/integration/ai-rules.md +141 -0
- package/knowledge/wallet-sdk-core/integration/architecture.md +212 -0
- package/knowledge/wallet-sdk-core/integration/features/README.md +22 -0
- package/knowledge/wallet-sdk-core/integration/features/bitcoin.md +103 -0
- package/knowledge/wallet-sdk-core/integration/features/evm.md +102 -0
- package/knowledge/wallet-sdk-core/integration/features/icon.md +88 -0
- package/knowledge/wallet-sdk-core/integration/features/injective.md +92 -0
- package/knowledge/wallet-sdk-core/integration/features/near.md +92 -0
- package/knowledge/wallet-sdk-core/integration/features/solana.md +104 -0
- package/knowledge/wallet-sdk-core/integration/features/stacks.md +91 -0
- package/knowledge/wallet-sdk-core/integration/features/stellar.md +95 -0
- package/knowledge/wallet-sdk-core/integration/features/sui.md +96 -0
- package/knowledge/wallet-sdk-core/integration/quickstart.md +259 -0
- package/knowledge/wallet-sdk-core/integration/recipes/README.md +15 -0
- package/knowledge/wallet-sdk-core/integration/recipes/bridge-to-sdk.md +145 -0
- package/knowledge/wallet-sdk-core/integration/recipes/defaults-and-overrides.md +159 -0
- package/knowledge/wallet-sdk-core/integration/recipes/library-exports.md +129 -0
- package/knowledge/wallet-sdk-core/integration/recipes/setup-browser-extension.md +137 -0
- package/knowledge/wallet-sdk-core/integration/recipes/setup-private-key.md +115 -0
- package/knowledge/wallet-sdk-core/integration/recipes/sign-and-broadcast.md +201 -0
- package/knowledge/wallet-sdk-core/integration/recipes/testing.md +163 -0
- package/knowledge/wallet-sdk-core/integration/reference/README.md +13 -0
- package/knowledge/wallet-sdk-core/integration/reference/chain-support.md +65 -0
- package/knowledge/wallet-sdk-core/integration/reference/glossary.md +28 -0
- package/knowledge/wallet-sdk-core/integration/reference/interfaces.md +131 -0
- package/knowledge/wallet-sdk-core/integration/reference/provider-classes.md +54 -0
- package/knowledge/wallet-sdk-core/integration/reference/public-api.md +128 -0
- package/knowledge/wallet-sdk-core/migration/README.md +84 -0
- package/knowledge/wallet-sdk-core/migration/ai-rules.md +139 -0
- package/knowledge/wallet-sdk-core/migration/breaking-changes/README.md +14 -0
- package/knowledge/wallet-sdk-core/migration/breaking-changes/base-wallet-provider.md +52 -0
- package/knowledge/wallet-sdk-core/migration/breaking-changes/defaults-config.md +57 -0
- package/knowledge/wallet-sdk-core/migration/breaking-changes/folder-layout.md +99 -0
- package/knowledge/wallet-sdk-core/migration/breaking-changes/library-exports.md +58 -0
- package/knowledge/wallet-sdk-core/migration/checklist.md +62 -0
- package/knowledge/wallet-sdk-core/migration/recipes/README.md +12 -0
- package/knowledge/wallet-sdk-core/migration/recipes/adopt-defaults.md +84 -0
- package/knowledge/wallet-sdk-core/migration/recipes/adopt-library-exports.md +99 -0
- package/knowledge/wallet-sdk-core/migration/reference/README.md +12 -0
- package/knowledge/wallet-sdk-core/migration/reference/added-fields.md +71 -0
- package/knowledge/wallet-sdk-core/migration/reference/deleted-exports.md +35 -0
- package/knowledge/wallet-sdk-core/migration/reference/renamed-symbols.md +31 -0
- package/knowledge/wallet-sdk-core/migration/reference/return-shapes.md +23 -0
- package/knowledge/wallet-sdk-react/AGENTS.md +46 -0
- package/knowledge/wallet-sdk-react/integration/README.md +103 -0
- package/knowledge/wallet-sdk-react/integration/ai-rules.md +136 -0
- package/knowledge/wallet-sdk-react/integration/architecture.md +185 -0
- package/knowledge/wallet-sdk-react/integration/examples/01-minimal-evm.tsx +75 -0
- package/knowledge/wallet-sdk-react/integration/examples/02-multi-chain-modal.tsx +169 -0
- package/knowledge/wallet-sdk-react/integration/examples/03-nextjs-app-router.tsx +99 -0
- package/knowledge/wallet-sdk-react/integration/examples/04-walletconnect-setup.tsx +89 -0
- package/knowledge/wallet-sdk-react/integration/examples/README.md +29 -0
- package/knowledge/wallet-sdk-react/integration/recipes/batch-operations.md +224 -0
- package/knowledge/wallet-sdk-react/integration/recipes/bridge-to-sdk.md +165 -0
- package/knowledge/wallet-sdk-react/integration/recipes/chain-detection.md +259 -0
- package/knowledge/wallet-sdk-react/integration/recipes/connect-button.md +159 -0
- package/knowledge/wallet-sdk-react/integration/recipes/multi-chain-modal.md +203 -0
- package/knowledge/wallet-sdk-react/integration/recipes/setup.md +163 -0
- package/knowledge/wallet-sdk-react/integration/recipes/sign-message.md +138 -0
- package/knowledge/wallet-sdk-react/integration/recipes/sub-path-imports.md +97 -0
- package/knowledge/wallet-sdk-react/integration/recipes/switch-chain.md +144 -0
- package/knowledge/wallet-sdk-react/integration/recipes/walletconnect-setup.md +139 -0
- package/knowledge/wallet-sdk-react/integration/reference/api-surface.md +176 -0
- package/knowledge/wallet-sdk-react/integration/reference/chain-support.md +79 -0
- package/knowledge/wallet-sdk-react/integration/reference/connectors.md +75 -0
- package/knowledge/wallet-sdk-react/integration/reference/hooks.md +212 -0
- package/knowledge/wallet-sdk-react/integration/reference/wallet-brands.md +107 -0
- package/knowledge/wallet-sdk-react/migration/README.md +49 -0
- package/knowledge/wallet-sdk-react/migration/ai-rules.md +144 -0
- package/knowledge/wallet-sdk-react/migration/breaking-changes.md +310 -0
- package/knowledge/wallet-sdk-react/migration/checklist.md +159 -0
- package/knowledge/wallet-sdk-react/migration/recipes/connect-button.md +170 -0
- package/knowledge/wallet-sdk-react/migration/recipes/multi-chain-modal.md +245 -0
- package/knowledge/wallet-sdk-react/migration/recipes/ssr-setup.md +165 -0
- package/knowledge/wallet-sdk-react/migration/recipes/walletconnect-migration.md +170 -0
- package/knowledge/wallet-sdk-react/migration/reference/components.md +75 -0
- package/knowledge/wallet-sdk-react/migration/reference/config.md +339 -0
- package/knowledge/wallet-sdk-react/migration/reference/hooks.md +336 -0
- package/knowledge/wallet-sdk-react/migration/reference/imports.md +158 -0
- package/package.json +59 -0
- package/skills/sodax-dapp-kit-integration/SKILL.md +71 -0
- package/skills/sodax-dapp-kit-migration/SKILL.md +58 -0
- package/skills/sodax-sdk-integration/SKILL.md +66 -0
- package/skills/sodax-sdk-migration/SKILL.md +75 -0
- package/skills/sodax-wallet-sdk-core-integration/SKILL.md +55 -0
- package/skills/sodax-wallet-sdk-core-migration/SKILL.md +56 -0
- package/skills/sodax-wallet-sdk-react-integration/SKILL.md +80 -0
- package/skills/sodax-wallet-sdk-react-migration/SKILL.md +71 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Recipe: Bridge to `@sodax/sdk`
|
|
2
|
+
|
|
3
|
+
Pass the constructed provider to `@sodax/sdk` so the SDK can sign and submit hub/spoke transactions on the user's behalf.
|
|
4
|
+
|
|
5
|
+
**Depends on:** a constructed provider (see [`setup-private-key.md`](./setup-private-key.md) or [`setup-browser-extension.md`](./setup-browser-extension.md)).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## The contract: `IXxxWalletProvider`
|
|
10
|
+
|
|
11
|
+
`@sodax/sdk` consumes the chain-specific **interfaces** from `@sodax/types`, not the concrete classes. This is the indirection that keeps the SDK decoupled from `wallet-sdk-core`:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import type {
|
|
15
|
+
IEvmWalletProvider,
|
|
16
|
+
ISolanaWalletProvider,
|
|
17
|
+
ISuiWalletProvider,
|
|
18
|
+
IBitcoinWalletProvider,
|
|
19
|
+
IStellarWalletProvider,
|
|
20
|
+
IIconWalletProvider,
|
|
21
|
+
IInjectiveWalletProvider,
|
|
22
|
+
INearWalletProvider,
|
|
23
|
+
IStacksWalletProvider,
|
|
24
|
+
} from '@sodax/types';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Each `*WalletProvider` class from `wallet-sdk-core` `implements` the matching interface. So:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
|
|
31
|
+
import type { IEvmWalletProvider } from '@sodax/types';
|
|
32
|
+
|
|
33
|
+
const evm: IEvmWalletProvider = new EvmWalletProvider({ /* … */ });
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
In your SDK call signatures, take the **interface**, not the class:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// ✅ DO
|
|
40
|
+
async function deposit(wallet: IEvmWalletProvider) { /* … */ }
|
|
41
|
+
|
|
42
|
+
// ❌ DON'T — couples the function to the implementation
|
|
43
|
+
async function deposit(wallet: EvmWalletProvider) { /* … */ }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Pattern: pass the provider to a `Sodax` feature service
|
|
49
|
+
|
|
50
|
+
Construct the wallet provider once, instantiate the `Sodax` facade, and pass the provider as `walletProvider` to the feature method you want (swap, bridge, money market, staking, …). The `Sodax` facade owns the per-chain spoke services internally — you do **not** construct `*SpokeService` yourself.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { Sodax } from '@sodax/sdk';
|
|
54
|
+
import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
|
|
55
|
+
import { ChainKeys } from '@sodax/types';
|
|
56
|
+
|
|
57
|
+
const walletProvider = new EvmWalletProvider({
|
|
58
|
+
privateKey: process.env.EVM_PK as `0x${string}`,
|
|
59
|
+
chainId: ChainKeys.SONIC_MAINNET,
|
|
60
|
+
rpcUrl: process.env.EVM_RPC,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const sodax = new Sodax(/* optional SodaxConfig — see @sodax/sdk docs */);
|
|
64
|
+
|
|
65
|
+
// Example: supply to the money market on BSC. The wallet provider goes in
|
|
66
|
+
// at the feature-method call, not at facade construction.
|
|
67
|
+
const result = await sodax.moneyMarket.supply({
|
|
68
|
+
params: {
|
|
69
|
+
srcChainKey: ChainKeys.BSC_MAINNET,
|
|
70
|
+
srcAddress: await walletProvider.getWalletAddress(),
|
|
71
|
+
token: '0x…',
|
|
72
|
+
amount: 1_000n,
|
|
73
|
+
action: 'supply',
|
|
74
|
+
},
|
|
75
|
+
walletProvider, // ← the IEvmWalletProvider
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The same shape applies to `sodax.swaps.*`, `sodax.bridge.*`, `sodax.staking.*`, `sodax.migration.*`, etc. — each feature service method that needs signing takes a `walletProvider` argument typed to the chain-specific interface.
|
|
80
|
+
|
|
81
|
+
> If you need the underlying spoke service for advanced read-only operations, get it via `sodax.spoke.getSpokeService(chainKey)` — but never `new EvmSpokeService(...)` yourself.
|
|
82
|
+
|
|
83
|
+
For SDK-level recipes (initialise the `Sodax` facade, configure hub provider, raw-tx flows, error handling) see the [`@sodax/sdk` knowledge tree](https://github.com/icon-project/sodax-sdks/tree/main/packages/skills/knowledge/sdk/) (sibling under `@sodax/skills`).
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Pattern: React layer (typical)
|
|
88
|
+
|
|
89
|
+
In a React dApp you almost never construct providers manually. `@sodax/wallet-sdk-react` returns the typed interface for you, and `@sodax/dapp-kit` wraps SDK calls into hooks:
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
93
|
+
import { useSwap } from '@sodax/dapp-kit';
|
|
94
|
+
import { ChainKeys } from '@sodax/types';
|
|
95
|
+
|
|
96
|
+
function SwapButton() {
|
|
97
|
+
const evm = useWalletProvider({ xChainId: ChainKeys.SONIC_MAINNET });
|
|
98
|
+
// evm: IEvmWalletProvider | undefined
|
|
99
|
+
|
|
100
|
+
const swap = useSwap();
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<button
|
|
104
|
+
disabled={!evm}
|
|
105
|
+
onClick={() => evm && swap.mutateAsync({ /* params */, walletProvider: evm })}
|
|
106
|
+
>
|
|
107
|
+
Swap
|
|
108
|
+
</button>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The hook narrows on `xChainId`, returns the chain-specific interface, and is `undefined` until the user is connected on that family. Refer to `@sodax/wallet-sdk-react`'s own docs for the full pattern.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Patterns to avoid
|
|
118
|
+
|
|
119
|
+
| Anti-pattern | Why bad | Replacement |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| Re-constructing the provider in every call site | Wastes work, can drop default config | Construct once, pass the instance around |
|
|
122
|
+
| Typing functions on the concrete class (`EvmWalletProvider`) | Couples to `wallet-sdk-core` | Use the `IXxxWalletProvider` interface |
|
|
123
|
+
| Casting between provider classes (`as ISolanaWalletProvider`) | Hides a chain-type mismatch | Pick the right provider for the chain at the call site |
|
|
124
|
+
| Storing the provider in a long-lived Zustand / Redux store | Provider holds live SDK clients / network connections | Store the **config** (e.g. PK + chainId), construct on demand |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Verification
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# 1. Type check passes
|
|
132
|
+
pnpm checkTs
|
|
133
|
+
|
|
134
|
+
# 2. SDK calls type-check against the interface, not the class
|
|
135
|
+
grep -rn "IEvmWalletProvider\|ISolanaWalletProvider\|IBitcoinWalletProvider" <user-src>
|
|
136
|
+
# expect at least one match in your function signatures
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Next steps
|
|
142
|
+
|
|
143
|
+
- [`defaults-and-overrides.md`](./defaults-and-overrides.md) — fine-tune the `defaults` slice for tx options.
|
|
144
|
+
- [`library-exports.md`](./library-exports.md) — type-only re-exports to avoid upstream chain-SDK deps.
|
|
145
|
+
- [`testing.md`](./testing.md) — mocking providers in tests.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Recipe: Defaults and per-call overrides
|
|
2
|
+
|
|
3
|
+
Configure the `defaults` slice and understand the shallow-merge semantics shared by every provider.
|
|
4
|
+
|
|
5
|
+
**Depends on:** [`setup-private-key.md`](./setup-private-key.md) or [`setup-browser-extension.md`](./setup-browser-extension.md).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Mental model
|
|
10
|
+
|
|
11
|
+
Every provider class extends `BaseWalletProvider<TDefaults>`. `defaults` is captured at construction time; per-call `options` are shallow-merged over the relevant slice at call time:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
final = shallowMerge(defaults[key], options) // mergePolicy('key', options)
|
|
15
|
+
OR
|
|
16
|
+
= shallowMerge(defaults, options) // mergeDefaults(options)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Two helpers, two shapes:
|
|
20
|
+
|
|
21
|
+
| Helper | When the chain uses it | Example |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `mergePolicy('foo', opts)` | `defaults` is **grouped per method** | EVM: `defaults.sendTransaction`, `defaults.waitForTransactionReceipt` |
|
|
24
|
+
| `mergeDefaults(opts)` | `defaults` is **flat** | Bitcoin: `defaultFinalize`; Stellar: `pollInterval`, `pollTimeout` |
|
|
25
|
+
|
|
26
|
+
For the helper each chain uses, see [`../features/<chain>.md`](../features/).
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Shallow, not deep
|
|
31
|
+
|
|
32
|
+
Top-level keys merge; **nested objects are replaced wholesale**.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
const provider = new EvmWalletProvider({
|
|
36
|
+
// …
|
|
37
|
+
defaults: {
|
|
38
|
+
sendTransaction: { gas: 3_000_000n, nonce: 0 },
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
await provider.sendTransaction(txData, { gas: 5_000_000n });
|
|
43
|
+
// ^^^^^^^^^^^^^^^^
|
|
44
|
+
// Final policy: { gas: 5_000_000n } ← nonce is DROPPED
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If you need `nonce` to persist, include it in the per-call options:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
await provider.sendTransaction(txData, { gas: 5_000_000n, nonce: 0 });
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Or split the default so each tunable lives at the top level — see `src/utils/merge.ts` for the implementation. The behavior is intentional: deep merge would silently smuggle stale fields across call sites.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## `undefined` is "no opinion"
|
|
58
|
+
|
|
59
|
+
The merge skips:
|
|
60
|
+
|
|
61
|
+
- `undefined` **layers** entirely (no options object → use defaults verbatim).
|
|
62
|
+
- `undefined` **values** inside a layer (`{ gas: undefined }` does **not** override the previous layer).
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const policy: Partial<EvmSendTransactionPolicy> = { gas: undefined };
|
|
66
|
+
await provider.sendTransaction(txData, policy);
|
|
67
|
+
// gas falls back to defaults.sendTransaction.gas
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This is useful when threading options through optional parameters — `undefined` reads as "use the default".
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Where to put what
|
|
75
|
+
|
|
76
|
+
| Tunable | Goes where | Why |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| Env-level constants (RPC URL, default gas, default commitment) | `defaults` at construction | One place, captured at startup |
|
|
79
|
+
| Per-call tweaks (this tx needs more gas) | per-call `options` argument | Localized, doesn't leak into other calls |
|
|
80
|
+
| Anything that changes after construction (active network in PK mode) | re-construct the provider | `defaults` is frozen at startup |
|
|
81
|
+
|
|
82
|
+
You **cannot** mutate `defaults` after construction — `BaseWalletProvider` captures the reference into a `protected readonly` field. Later mutations have no effect.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Worked example: EVM with two default slices
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
|
|
90
|
+
import { ChainKeys } from '@sodax/types';
|
|
91
|
+
|
|
92
|
+
const provider = new EvmWalletProvider({
|
|
93
|
+
privateKey: process.env.PK as `0x${string}`,
|
|
94
|
+
chainId: ChainKeys.SONIC_MAINNET,
|
|
95
|
+
defaults: {
|
|
96
|
+
// Slice grouped by method — merged via mergePolicy('sendTransaction', …)
|
|
97
|
+
sendTransaction: { gas: 3_000_000n },
|
|
98
|
+
|
|
99
|
+
// Another method-grouped slice
|
|
100
|
+
waitForTransactionReceipt: { confirmations: 1, timeout: 60_000 },
|
|
101
|
+
|
|
102
|
+
// Constructor-time slices (private-key mode only — ignored in browser-extension mode)
|
|
103
|
+
transport: { batch: { batchSize: 10 } },
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Default gas: 3M. This call bumps to 5M.
|
|
108
|
+
const hash = await provider.sendTransaction(tx, { gas: 5_000_000n });
|
|
109
|
+
|
|
110
|
+
// Default 1 confirmation, 60s timeout. This call overrides both.
|
|
111
|
+
const receipt = await provider.waitForTransactionReceipt(hash, {
|
|
112
|
+
confirmations: 2,
|
|
113
|
+
timeout: 30_000,
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Browser-extension warning
|
|
120
|
+
|
|
121
|
+
In **browser-extension** mode the constructor-time slices (`transport`, `publicClient`, `walletClient` on EVM; analogous on other chains) are **ignored** — the consumer already supplied built clients, so there is nothing for the provider to configure. A one-time `console.warn` is logged.
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
[EvmWalletProvider] defaults.{transport,publicClient,walletClient} ignored in browser-extension mode.
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This is informational, not a bug. The method-grouped slices (`sendTransaction`, `waitForTransactionReceipt`, …) still apply in both modes.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Verification
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
// Assert that defaults applied — run on a testnet
|
|
135
|
+
const hash = await provider.sendTransaction(tx); // no per-call options
|
|
136
|
+
// Then read the receipt and confirm gas matches your default
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
pnpm checkTs
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Common pitfalls
|
|
146
|
+
|
|
147
|
+
| Pitfall | Symptom | Fix |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| Expecting deep merge | A nested field was "dropped" | The whole object was replaced. Include both fields in the per-call options. |
|
|
150
|
+
| Mutating `defaults` after construction | Tunable doesn't take effect | Reconstruct the provider, or pass the new value per call. |
|
|
151
|
+
| Setting transport defaults in browser-extension mode | Warning logged, no effect | Move them out — they only apply in PK mode. |
|
|
152
|
+
| Putting RPC URL in `defaults` | RPC URL is a top-level config field on every chain, not a `defaults` slice | Use `rpcUrl: '…'` at the config root (PK mode), or pass `publicClient` / `client` directly (browser-extension mode). |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## See also
|
|
157
|
+
|
|
158
|
+
- [`../architecture.md`](../architecture.md) § `BaseWalletProvider` and the `defaults` model.
|
|
159
|
+
- [`../features/`](../features/) — per-chain `*Defaults` shape and which helper each chain uses.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Recipe: `library-exports` — re-import upstream chain types
|
|
2
|
+
|
|
3
|
+
Avoid adding `viem`, `@mysten/sui`, `@solana/web3.js`, etc. as direct `package.json` deps. `@sodax/wallet-sdk-core` re-exports a curated set of types (and a handful of runtime enums) from each upstream chain SDK.
|
|
4
|
+
|
|
5
|
+
**Depends on:** none — pure type-level optimisation.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What's re-exported
|
|
10
|
+
|
|
11
|
+
Source file: `src/types/library-exports.ts`. The export name is the same as upstream — only the source module changes.
|
|
12
|
+
|
|
13
|
+
### Types (no runtime cost)
|
|
14
|
+
|
|
15
|
+
| Chain SDK | Re-exported types |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `viem` | `Account`, `Address`, `Chain`, `Transport`, `PublicClient`, `WalletClient`, `HttpTransportConfig`, `PublicClientConfig`, `WalletClientConfig`, `SendTransactionParameters`, `WaitForTransactionReceiptParameters`, `TransactionReceipt` |
|
|
18
|
+
| `@mysten/sui/client` | `SuiTransactionBlockResponseOptions` |
|
|
19
|
+
| `@mysten/sui/transactions` | `Transaction`, `TransactionArgument` |
|
|
20
|
+
| `@mysten/wallet-standard` | `SuiWalletFeatures`, `WalletAccount`, `WalletWithFeatures` |
|
|
21
|
+
| `@solana/web3.js` | `Commitment`, `ConnectionConfig`, `SendOptions` |
|
|
22
|
+
| `@injectivelabs/networks` | `Network` |
|
|
23
|
+
| `@injectivelabs/ts-types` | `ChainId`, `EvmChainId` |
|
|
24
|
+
| `@injectivelabs/wallet-core` | `MsgBroadcaster` |
|
|
25
|
+
| `@stacks/transactions` | `ClarityValue`, `PostConditionModeName` |
|
|
26
|
+
| `@stacks/network` | `StacksNetwork` |
|
|
27
|
+
| `@stacks/connect` | `StacksProvider` |
|
|
28
|
+
| `near-api-js` | `KeyPairString` |
|
|
29
|
+
| `@hot-labs/near-connect` | `NearConnector` |
|
|
30
|
+
| `bitcoinjs-lib/src/networks.js` | `Network as BitcoinJsNetwork` |
|
|
31
|
+
|
|
32
|
+
### Runtime values (also re-exported)
|
|
33
|
+
|
|
34
|
+
| Source | Value | Why include the runtime |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `@stellar/stellar-sdk` | `Networks` (object) | Consumers commonly read `Networks.PUBLIC` / `Networks.TESTNET` |
|
|
37
|
+
| `@stacks/transactions` | `PostConditionMode` (enum) | Used as a value when building Stacks tx params |
|
|
38
|
+
|
|
39
|
+
Note the file name: `library-exports` (not `library-types`). It exists precisely because the file mixes type and runtime re-exports.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// ✅ DO — types and the two runtime enums via wallet-sdk-core
|
|
47
|
+
import type {
|
|
48
|
+
WalletClient,
|
|
49
|
+
PublicClient,
|
|
50
|
+
TransactionReceipt,
|
|
51
|
+
SuiWalletFeatures,
|
|
52
|
+
WalletAccount,
|
|
53
|
+
WalletWithFeatures,
|
|
54
|
+
ConnectionConfig,
|
|
55
|
+
Network,
|
|
56
|
+
ChainId,
|
|
57
|
+
StacksNetwork,
|
|
58
|
+
StacksProvider,
|
|
59
|
+
NearConnector,
|
|
60
|
+
} from '@sodax/wallet-sdk-core';
|
|
61
|
+
|
|
62
|
+
import { Networks, PostConditionMode } from '@sodax/wallet-sdk-core';
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// ❌ DON'T — direct upstream imports for these names if you only need them as types
|
|
67
|
+
import type { WalletClient } from 'viem';
|
|
68
|
+
import { Networks } from '@stellar/stellar-sdk';
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## When to NOT use re-exports
|
|
74
|
+
|
|
75
|
+
The re-export list is **curated** — only the types most consumers need. Use the upstream package directly when:
|
|
76
|
+
|
|
77
|
+
- You need a type not in the re-export list (e.g. viem's `TransactionRequest`, Solana's `Keypair` value).
|
|
78
|
+
- You need a **runtime value** other than `Networks` / `PostConditionMode` (e.g. viem's `createPublicClient`, `@solana/web3.js`'s `Connection`).
|
|
79
|
+
- You are building a polyfill, mock, or shim around the underlying SDK.
|
|
80
|
+
|
|
81
|
+
In those cases, add the upstream package to `package.json` and import normally. The re-export is an optimisation, not a hard wall.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Why `library-exports` exists
|
|
86
|
+
|
|
87
|
+
| Without it | With it |
|
|
88
|
+
|---|---|
|
|
89
|
+
| Consumer `package.json` lists 8+ chain SDKs explicitly | Consumer lists only `@sodax/wallet-sdk-core` + `@sodax/types` |
|
|
90
|
+
| Upgrading a chain SDK touches consumer lockfiles | SODAX bumps the SDK; consumers re-install |
|
|
91
|
+
| Type drift between SODAX and consumer (different `viem` minor versions) | Single source of truth — same `viem` version as SODAX uses internally |
|
|
92
|
+
|
|
93
|
+
The trade-off is the curated list — uncommon types need a direct dep.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Verification
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 1. Type check
|
|
101
|
+
pnpm checkTs
|
|
102
|
+
|
|
103
|
+
# 2. Confirm no direct upstream imports for re-exported types
|
|
104
|
+
grep -rn "from 'viem'" <user-src> | grep -E "WalletClient|PublicClient|TransactionReceipt|SendTransactionParameters"
|
|
105
|
+
grep -rn "from '@stellar/stellar-sdk'" <user-src> | grep "Networks"
|
|
106
|
+
grep -rn "from '@stacks/transactions'" <user-src> | grep "PostConditionMode"
|
|
107
|
+
# expect empty for all three
|
|
108
|
+
|
|
109
|
+
# 3. Confirm the chain SDKs are NOT direct deps in consumer's package.json
|
|
110
|
+
cat <user>/package.json | grep -E '"viem"|"@stellar/stellar-sdk"|"@stacks/transactions"|"@mysten/sui"|"@solana/web3.js"|"@injectivelabs"|"near-api-js"|"bitcoinjs-lib"'
|
|
111
|
+
# expect empty unless the consumer legitimately uses a non-re-exported symbol
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Common pitfalls
|
|
117
|
+
|
|
118
|
+
| Pitfall | Symptom | Fix |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| Importing `Networks` from `@stellar/stellar-sdk` after install | Works, but adds a direct dep | Switch to `import { Networks } from '@sodax/wallet-sdk-core'` |
|
|
121
|
+
| Mixing type-only and value imports in one statement | Build size grows | `import type { … }` for types; separate value imports |
|
|
122
|
+
| Expecting all viem helpers to be re-exported | `createPublicClient` is missing | Only types + 2 enums are re-exported. Other runtime helpers require direct install. |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## See also
|
|
127
|
+
|
|
128
|
+
- [`../architecture.md`](../architecture.md) § `library-exports` — the upstream-SDK indirection.
|
|
129
|
+
- [`../reference/public-api.md`](../reference/public-api.md) — full barrel export list.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Recipe: Setup — browser-extension mode
|
|
2
|
+
|
|
3
|
+
Construct a `*WalletProvider` from a wallet adapter that the user has already connected (MetaMask via wagmi, Phantom via wallet-adapter, Xverse via a kit, …).
|
|
4
|
+
|
|
5
|
+
**Depends on:** the consumer app already obtains a chain-specific signer / client from the extension. Inside a React app, prefer `useWalletProvider` from `@sodax/wallet-sdk-react` — see § "When to skip this recipe" below.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Pick the right chain
|
|
10
|
+
|
|
11
|
+
Each chain has its own browser-extension variant. See [`../features/<chain>.md`](../features/) for exact field shapes.
|
|
12
|
+
|
|
13
|
+
| Chain | Required inputs |
|
|
14
|
+
|---|---|
|
|
15
|
+
| EVM | `walletClient` (viem `WalletClient<Transport, Chain, Account>`) + `publicClient` (viem `PublicClient`) |
|
|
16
|
+
| Solana | `wallet: { publicKey, signTransaction }` + `endpoint` |
|
|
17
|
+
| Sui | `client` (`SuiClient`) + `wallet` (`WalletWithFeatures<Partial<SuiWalletFeatures>>`) + `account` (`WalletAccount`) |
|
|
18
|
+
| Bitcoin | `type: 'BROWSER_EXTENSION'`, `walletsKit` (consumer-supplied adapter), `network` |
|
|
19
|
+
| Stellar | `type: 'BROWSER_EXTENSION'`, `walletsKit`, `network` |
|
|
20
|
+
| ICON | `walletAddress` (optional `hx…`) + `rpcUrl` |
|
|
21
|
+
| Injective | `msgBroadcaster` |
|
|
22
|
+
| NEAR | `wallet` (`NearConnector` from `@hot-labs/near-connect`) |
|
|
23
|
+
| Stacks | `address` + optional `provider` (StacksProvider) |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Pattern: EVM (with wagmi clients)
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
|
|
31
|
+
import type { WalletClient, PublicClient } from '@sodax/wallet-sdk-core';
|
|
32
|
+
import { useWalletClient, usePublicClient } from 'wagmi';
|
|
33
|
+
// …or wherever your app sources the viem clients
|
|
34
|
+
|
|
35
|
+
function buildProvider(walletClient: WalletClient, publicClient: PublicClient) {
|
|
36
|
+
return new EvmWalletProvider({
|
|
37
|
+
walletClient,
|
|
38
|
+
publicClient,
|
|
39
|
+
// Optional — `defaults.sendTransaction` and `defaults.waitForTransactionReceipt`
|
|
40
|
+
// are honored. `defaults.transport / publicClient / walletClient` are IGNORED
|
|
41
|
+
// in browser-extension mode (the provider logs a one-time warning).
|
|
42
|
+
defaults: {
|
|
43
|
+
sendTransaction: { gas: 1_000_000n },
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Pattern: Solana (with `@solana/wallet-adapter-react`)
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { SolanaWalletProvider } from '@sodax/wallet-sdk-core';
|
|
55
|
+
import { useWallet } from '@solana/wallet-adapter-react';
|
|
56
|
+
|
|
57
|
+
function buildProvider() {
|
|
58
|
+
const { publicKey, signTransaction } = useWallet();
|
|
59
|
+
return new SolanaWalletProvider({
|
|
60
|
+
wallet: { publicKey, signTransaction }, // both may be null/undefined until connected
|
|
61
|
+
endpoint: 'https://api.mainnet-beta.solana.com',
|
|
62
|
+
defaults: { sendOptions: { skipPreflight: false } },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Pattern: Bitcoin / Stellar (explicit `type`)
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { BitcoinWalletProvider } from '@sodax/wallet-sdk-core';
|
|
73
|
+
|
|
74
|
+
const provider = new BitcoinWalletProvider({
|
|
75
|
+
type: 'BROWSER_EXTENSION',
|
|
76
|
+
walletsKit: myBitcoinAdapter, // implements BitcoinWalletsKit
|
|
77
|
+
network: 'MAINNET',
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The `walletsKit` is a consumer-provided adapter (Xverse / Unisat / OKX) that conforms to the `BitcoinWalletsKit` interface — see [`../features/bitcoin.md`](../features/bitcoin.md).
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## When to skip this recipe
|
|
86
|
+
|
|
87
|
+
You almost never construct browser-extension providers **manually** inside a React component. The right path is:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
91
|
+
import { ChainKeys } from '@sodax/types';
|
|
92
|
+
|
|
93
|
+
const evm = useWalletProvider({ xChainId: ChainKeys.SONIC_MAINNET });
|
|
94
|
+
// evm: IEvmWalletProvider | undefined ← already typed, already wired
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`@sodax/wallet-sdk-react` handles the construction internally — see [`@sodax/wallet-sdk-react`: `integration/recipes/setup.md`](https://github.com/icon-project/sodax-sdks/blob/main/packages/skills/knowledge/wallet-sdk-react/integration/recipes/setup.md). Skip this recipe (the manual path) unless you are:
|
|
98
|
+
|
|
99
|
+
- Building a custom non-React frontend that talks to a wallet extension directly.
|
|
100
|
+
- Writing a thin wrapper around the package for a framework that doesn't have a SODAX integration yet.
|
|
101
|
+
- Migrating a legacy non-React app.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Verification
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
console.log(await provider.getWalletAddress()); // smoke test
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Type check
|
|
113
|
+
pnpm checkTs
|
|
114
|
+
|
|
115
|
+
# Confirm no deep imports
|
|
116
|
+
grep -rn "@sodax/wallet-sdk-core/" <user-src> | grep -v "from '@sodax/wallet-sdk-core'"
|
|
117
|
+
# expect empty
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Common errors
|
|
123
|
+
|
|
124
|
+
| Error | Cause | Fix |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| `signTransaction is not a function` (Solana) | Wallet adapter didn't provide a signer for the connected wallet | Gate construction on `signTransaction != null`. |
|
|
127
|
+
| `WalletAccount is undefined` (Sui) | Adapter exposes `wallet` but not the active `account` | Read `wallet.accounts[0]` or your adapter's "current account" API before constructing. |
|
|
128
|
+
| `[EvmWalletProvider] defaults.{transport,publicClient,walletClient} ignored…` | Mixed PK-mode defaults with browser-extension config | Move those defaults out — they only apply in private-key mode. |
|
|
129
|
+
| Mode picked the wrong variant (TypeScript narrowing fails) | Mixed PK and browser fields | Pick **one** discriminated union variant. Don't pass both. |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Next steps
|
|
134
|
+
|
|
135
|
+
- [`bridge-to-sdk.md`](./bridge-to-sdk.md) — hand off the provider to `@sodax/sdk` calls.
|
|
136
|
+
- [`library-exports.md`](./library-exports.md) — avoid taking `viem` / `@mysten/sui` / etc. as direct deps when importing types.
|
|
137
|
+
- [`defaults-and-overrides.md`](./defaults-and-overrides.md) — tune `defaults`.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Recipe: Setup — private-key mode
|
|
2
|
+
|
|
3
|
+
Construct a `*WalletProvider` from a raw key. Use this in Node scripts, CI, tests, indexers, bots — anywhere the runtime legitimately possesses a secret.
|
|
4
|
+
|
|
5
|
+
**Depends on:** none. **Do NOT** use this in a browser bundle.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Pick the right chain
|
|
10
|
+
|
|
11
|
+
Each chain has its own discriminated union. See [`../features/<chain>.md`](../features/) for exact field names.
|
|
12
|
+
|
|
13
|
+
| Chain | Field that triggers PK mode | Credential shape |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| EVM | `privateKey: '0x…'` | hex string |
|
|
16
|
+
| Solana | `privateKey: Uint8Array` | 64-byte secret key |
|
|
17
|
+
| Sui | `mnemonics: '…'` | BIP-39 phrase (no raw key option) |
|
|
18
|
+
| Bitcoin | `type: 'PRIVATE_KEY'`, `privateKey: '0x…'`| hex string + uppercase `type` |
|
|
19
|
+
| Stellar | `type: 'PRIVATE_KEY'`, `privateKey: '0x…'`| hex string + uppercase `type` |
|
|
20
|
+
| ICON | `privateKey: '0x…'` | hex string |
|
|
21
|
+
| Injective | `secret: { privateKey } \| { mnemonics }` | nested credential object |
|
|
22
|
+
| NEAR | `privateKey: 'ed25519:…'`, `accountId` | algorithm-prefixed string + accountId |
|
|
23
|
+
| Stacks | `privateKey: '…'` | string |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add @sodax/wallet-sdk-core @sodax/types
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
If you'll hand off to `@sodax/sdk`, add it too:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm add @sodax/sdk
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Pattern: EVM (representative)
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import 'dotenv/config';
|
|
45
|
+
import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
|
|
46
|
+
import { ChainKeys } from '@sodax/types';
|
|
47
|
+
|
|
48
|
+
const PRIVATE_KEY = process.env.EVM_PRIVATE_KEY as `0x${string}`;
|
|
49
|
+
if (!PRIVATE_KEY) throw new Error('EVM_PRIVATE_KEY is required');
|
|
50
|
+
|
|
51
|
+
const provider = new EvmWalletProvider({
|
|
52
|
+
privateKey: PRIVATE_KEY,
|
|
53
|
+
chainId: ChainKeys.SONIC_MAINNET, // pick any EvmChainKey
|
|
54
|
+
rpcUrl: process.env.EVM_RPC_URL, // optional — defaults to viem chain's public RPC
|
|
55
|
+
defaults: {
|
|
56
|
+
sendTransaction: { gas: 3_000_000n }, // env-level fixed default
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const address = await provider.getWalletAddress();
|
|
61
|
+
console.log('Signing as:', address);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
For other chains, swap the import and follow the field table above. Full snippets per chain live in [`../quickstart.md`](../quickstart.md).
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Keep the secret out of code
|
|
69
|
+
|
|
70
|
+
| Anti-pattern | Why bad | Replacement |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `privateKey: '0xabc…'` inline | Key in version control | `process.env.EVM_PRIVATE_KEY` |
|
|
73
|
+
| `.env` committed to git | Same as above | `.env` in `.gitignore`, only `.env.example` committed |
|
|
74
|
+
| Key in a frontend bundle | Browser users can read it | Use `setup-browser-extension.md` |
|
|
75
|
+
| Key passed via CLI argv | Shows up in shell history | `dotenv-cli` + `.env` file |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Verification
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// Get-address smoke test
|
|
83
|
+
console.log(await provider.getWalletAddress());
|
|
84
|
+
|
|
85
|
+
// Optional: dry-run a balance read
|
|
86
|
+
// (chain-specific — see ../features/<chain>.md)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# 1. Type check passes
|
|
91
|
+
pnpm checkTs
|
|
92
|
+
|
|
93
|
+
# 2. Confirm only one provider import — barrel only
|
|
94
|
+
grep -rn "from '@sodax/wallet-sdk-core" <script-dir>
|
|
95
|
+
# expect zero deep paths like @sodax/wallet-sdk-core/src/...
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Common errors
|
|
101
|
+
|
|
102
|
+
| Error | Cause | Fix |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `Invalid EVM wallet config` | Mixed PK and browser-extension fields in one object | Pick **one** variant. Don't pass both `privateKey` and `walletClient`. |
|
|
105
|
+
| TS2322: `'string'` is not assignable to `` `0x${string}` `` | Missing hex prefix or wrong type | Read from env with `as \`0x${string}\`` after a runtime check. |
|
|
106
|
+
| TS: `Property 'secret' is missing` (Injective) | Used `privateKey` at top level | Wrap in `{ secret: { privateKey } }` or `{ secret: { mnemonics } }`. See [`../features/injective.md`](../features/injective.md). |
|
|
107
|
+
| `Cannot find module 'viem/chains'` for unknown chain | Passed an EVM chain key not in `getEvmViemChain` | Use a `ChainKeys.*_MAINNET` constant — the function is exhaustive. |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Next steps
|
|
112
|
+
|
|
113
|
+
- [`bridge-to-sdk.md`](./bridge-to-sdk.md) — pass the provider to `@sodax/sdk` for swap / lend / bridge / stake.
|
|
114
|
+
- [`defaults-and-overrides.md`](./defaults-and-overrides.md) — tune the `defaults` slice.
|
|
115
|
+
- [`sign-and-broadcast.md`](./sign-and-broadcast.md) — chain-by-chain raw-tx flow.
|