Setup Wallet Providers
The SODAX SDK does not force you to use a specific wallet library. Instead, SDK calls accept an IWalletProvider implementation that you supply — either by using the ready-made implementations in @sodax/wallet-sdk-core, or by writing your own against the interface contracts in @sodax/sdk.
Table of Contents
1. Supported provider interfaces
Every chain family has a named interface that @sodax/sdk exports:
Interface
chainType literal
Chains covered
IEvmWalletProvider
'EVM'
Sonic (hub), Ethereum, Arbitrum, Base, BSC, Optimism, Polygon, Avalanche, HyperEVM, Lightlink, Redbelly, Kaia, Hedera
ISolanaWalletProvider
'SOLANA'
Solana
ISuiWalletProvider
'SUI'
Sui
IIconWalletProvider
'ICON'
ICON
IInjectiveWalletProvider
'INJECTIVE'
Injective
IStellarWalletProvider
'STELLAR'
Stellar
IStacksWalletProvider
'STACKS'
Stacks
IBitcoinWalletProvider
'BITCOIN'
Bitcoin
INearWalletProvider
'NEAR'
NEAR
All interfaces extend WalletAddressProvider (from @sodax/sdk), which requires:
The full union of all nine interfaces is IWalletProvider. GetWalletProviderType<K> maps a chain key or ChainType literal to the appropriate specific interface.
2. WalletProviderSlot — compile-time enforcement
Every SDK method that executes a transaction uses WalletProviderSlot<K, Raw> (defined in packages/types/src/common/common.ts) to enforce the pairing between raw mode and the presence of a wallet provider at compile time:
Three rules enforced by TypeScript:
raw: true—walletProvideris forbidden (?: nevermakes any value a type error). The SDK returns an unsigned transaction payload (TxReturnType<K, true>, e.g.EvmRawTransaction).raw: false(or omitted) —walletProvideris required and is chain-narrowed to the exact interface forKviaGetWalletProviderType<K>. The SDK signs and broadcasts, returning a transaction hash (TxReturnType<K, false>, e.g.Hash).Chain narrowing flows from the chain key — when the caller passes a literal chain key such as
ChainKeys.ETHEREUM_MAINNET, TypeScript preserves that as a value type, resolvingGetWalletProviderType<typeof ChainKeys.ETHEREUM_MAINNET>toIEvmWalletProviderautomatically.
3. wallet-sdk-core: ready-to-use implementations
Install the package:
The package is dependency-free from React and can be used directly in Node.js scripts, bots, and server environments, as well as in browser dApps.
Each chain provider lives under src/wallet-providers/<chain>/:
BaseWalletProvider
All nine provider classes extend BaseWalletProvider<TDefaults>:
Subclass constructors call super(config.defaults). Per-call overrides shallow-merge over the stored defaults at invocation time — nested objects replace wholesale rather than deep-merging.
chainType discriminant
Every I*WalletProvider interface declares readonly chainType as a string literal. This lets both the SDK and application code discriminate at runtime without instanceof:
Valid chainType values: 'EVM', 'BITCOIN', 'SOLANA', 'STELLAR', 'SUI', 'ICON', 'INJECTIVE', 'STACKS', 'NEAR'.
packages/sdk/src/shared/guards.ts also exposes named guards for the most common cases:
Dual config modes (private-key vs browser-extension)
Every provider accepts a discriminated-union config: one variant for server-side/script usage (private key) and one for dApp usage (pre-built client from a browser wallet). Discriminant mechanism varies by chain:
Field presence — privateKey field present vs. absent
EVM, ICON, Solana, Sui (uses mnemonics), NEAR
Explicit type field ('PRIVATE_KEY' / 'BROWSER_EXTENSION')
Bitcoin, Stellar
secret nested object ({ privateKey } or { mnemonics }) vs. msgBroadcaster
Injective
Field presence — privateKey present vs. absent
Stacks
All config types include an optional defaults field for per-method behavioral overrides.
Provider reference
Chain
Provider class
Native SDK
chainType
EVM (12 chains)
EvmWalletProvider
viem
'EVM'
Solana
SolanaWalletProvider
@solana/web3.js
'SOLANA'
Sui
SuiWalletProvider
@mysten/sui
'SUI'
ICON
IconWalletProvider
icon-sdk-js
'ICON'
Injective
InjectiveWalletProvider
@injectivelabs/sdk-ts
'INJECTIVE'
Stellar
StellarWalletProvider
@stellar/stellar-sdk
'STELLAR'
Stacks
StacksWalletProvider
@stacks/transactions
'STACKS'
Bitcoin
BitcoinWalletProvider
bitcoinjs-lib (PSBT)
'BITCOIN'
NEAR
NearWalletProvider
near-api-js
'NEAR'
4. Config type reference per chain
EVM (EvmWalletProvider)
EvmWalletProvider)EvmWalletDefaults accepts: sendTransaction, waitForTransactionReceipt, publicClient, walletClient, transport (all optional; applied per-call via mergePolicy).
Solana (SolanaWalletProvider)
SolanaWalletProvider)SolanaWalletDefaults accepts: connectionCommitment, connectionConfig, sendOptions, confirmCommitment.
Sui (SuiWalletProvider)
SuiWalletProvider)SuiWalletDefaults accepts: signAndExecuteTxn (dry-run toggle + response options), getCoins (pagination limit).
ICON (IconWalletProvider)
IconWalletProvider)IconWalletDefaults accepts: stepLimit, version, timestampProvider, jsonRpcId.
Note:
rpcUrlis typed as`http${string}`(template literal), not a barestring. EVM and InjectiverpcUrlfields have the same constraint. If you pass astringfrom an environment variable, either narrow it explicitly (e.g.process.env.RPC_URL as \http${string}``) or validate at the boundary.
Injective (InjectiveWalletProvider)
InjectiveWalletProvider)InjectiveWalletDefaults accepts: defaultFunds, defaultMemo, sequence, accountNumber.
Stellar (StellarWalletProvider)
StellarWalletProvider)StellarWalletDefaults accepts: pollInterval, pollTimeout, networkPassphrase.
Stacks (StacksWalletProvider)
StacksWalletProvider)StacksWalletDefaults accepts: network ('mainnet' | 'testnet'), postConditionMode.
Bitcoin (BitcoinWalletProvider)
BitcoinWalletProvider)BitcoinWalletDefaults accepts: defaultFinalize (whether to finalize PSBTs before returning).
NEAR (NearWalletProvider)
NearWalletProvider)NearWalletDefaults accepts: throwOnFailure, waitUntil, gasDefault, depositDefault.
5. React integration — useWalletProvider
packages/wallet-sdk-react provides useWalletProvider — a hook that reads the chain-appropriate provider from the Zustand store and returns it typed to the correct I*WalletProvider interface.
Pass xChainId or xChainType, never both — the hook asserts this at runtime and the overloads enforce it at compile time.
The returned provider is ready to pass directly into any SDK call's walletProvider slot:
Wallet providers are populated into the store by:
Provider-managed chains (EVM, Solana, Sui) — Hydrator components (
EvmHydrator,SolanaHydrator,SuiHydrator) sync the native SDK state into the store as the sole writers.Non-provider chains (Bitcoin, ICON, Injective, Stellar, NEAR, Stacks) — providers are created as a side-effect of
setXConnection()in the store, triggered when a user connects a wallet throughChainActions.
Configure which chains are active by passing a config prop to SodaxWalletProvider:
Omit a chain-type key entirely to skip mounting that adapter. useWalletProvider will return undefined for disabled chains and emit a one-time console warning.
6. Custom implementations
You can implement the SDK interfaces directly without using @sodax/wallet-sdk-core. Each interface is defined in @sodax/sdk (e.g. IEvmWalletProvider in @sodax/sdk):
Requirements for a valid custom implementation:
Declare
readonly chainType = '<CHAIN>' as const— the SDK anduseWalletProviderboth read this field for runtime dispatch. The value must exactly match thechainTypeliteral of the target interface.Implement every method on the interface — TypeScript will flag missing methods at compile time.
No base class required — extending
BaseWalletProvideris optional; it only provides thedefaultsstorage and merge helpers from@sodax/wallet-sdk-core.
Last updated