Wallet Provider
Spice Flow uses Privy for wallet connections and embedded wallets.Privy
Best for embedded wallets and social logins.PrivyProvider (which the SDK reads through Privy’s hooks), not on SpiceFlowProvider:
privyAppId and embeddedWalletConfig props on SpiceFlowProvider exist for compatibility but
have no effect in the current release.
Get Your Privy App ID:
- Sign up at privy.io
- Create a new app
- Copy your App ID from the dashboard
Execution Modes
Spice Flow supports three execution modes.7702 Mode (Default)
Uses EIP 7702 with embedded wallets. The solver executes transactions on behalf of the user via delegate contracts. This is the default and recommended mode for most chains.Presign Mode
Users sign all transactions upfront using their external wallet. Used for chains that don’t support EIP 7702.Ondemand Mode
Each transaction is signed on demand during execution. The app handles execution viaonDepositExecute / onWithdrawExecute callbacks.
In
presign and ondemand modes, the embedded wallet flow is skipped. Components use callback props (like onDepositExecute) instead of the solver execution path.Card and Exchange Deposits
Available from@spicenet-io/spiceflow-ui@4.7.11. When enabled, SpiceDeposit opens with a source
chooser in front of the existing flow: Wallet, Card, or Exchange. Card and exchange deposits
run through the Swapper Finance widget, and the SDK verifies on chain that the USDC arrived before handing
off. Users can fund with a debit card or from an exchange account instead of only from a connected wallet.
It is off by default. Nothing changes for your integration until you opt in:
enabled: true is the only required field. The integrator id defaults to Spicenet’s; pass
integratorId only if Swapper has issued you your own.
Where the funds land
Swapper delivers USDC to the wallet the user is operating with, and the wallet mode decides what happens next.
Swapper currently delivers to Base and Arbitrum. An embedded deposit always lands on Arbitrum
because escrow abstracts the chain downstream. An external deposit lands on your app’s chain when Swapper
covers it, and on Arbitrum when it does not. The app’s chain is read from
destinationChainId on
SpiceDeposit, falling back to nativeChainId on the provider.
If your app runs on a chain Swapper does not deliver to, an external-wallet user’s card or exchange deposit
ends up on Arbitrum, in their own wallet. Consider enabling this only for embedded-wallet users on those
chains, or make sure your flow can handle funds arriving there.
Telling the two outcomes apart
onDepositSuccess on SpiceDeposit reports which path completed through detail.type:
"deposit" keeps working and will not treat a wallet funding as a spice
credit.
The source chooser only appears on network="mainnet"; testnets skip it and go straight to the wallet
flow.
Network Configuration
Set the network to control which chains are available:Default Chains by Network
As of@spicenet-io/spiceflow-ui@4.7.9:
Mainnet: Ethereum (1), Base (8453), Arbitrum (42161), Citrea (4114), Robinhood (4663), BSC (56), Polygon (137), Monad (143)
Testnet: Sepolia (11155111), Arbitrum Sepolia (421614), Base Sepolia (84532), Citrea Testnet (5115), Base Camp (123420001114), Pharos (688688), Pharos Atlantic (688689), Robinhood Testnet (46630), Monad Testnet (10143), BSC Testnet (97), Avalanche Fuji (43113), Polygon Amoy (80002), Optimism Sepolia (11155420)
The list grows with releases — read it from your installed version with getChainIdsByNetwork("mainnet") (exported from the SDK) rather than hardcoding.
Custom Chain IDs
Override the defaults withsupportedChainIds:
Liquidity Venues
Available from@spicenet-io/spiceflow-ui@4.8.0. When a flow has to swap on the destination chain,
the SDK quotes every liquidity venue that covers that chain and takes the best fill: the most output
for an exact input, the least input for an exact output. Routing is decided in the SDK, on your RPC.
The solver only executes the calls the winning quote produced.
Leave liquidityVenues off and you get the built-in venues:
Every built-in serves both swap directions, so a venue is never reachable for an exact-input swap
but missing for an exact-output one.
Adding your own venue
Declare it once on the provider and every component picks it up. This is the whole change needed to route through a deployment the SDK does not ship — here, the SushiSwap v3 deployment on Robinhood:Turning the built-ins off
SetincludeDefaults: false to drop every built-in venue, including 1inch, and route only through
what you declared:
includeDefaults off (or true) to keep the built-ins and
add yours alongside them.
Venue fields
Supply the deployment’s addresses, not a pool address. A v3-style pool calls back intomsg.sender, so swaps go through the router and quotes through the quoter; the SDK finds the pools
itself from the fee tiers (or tick spacings) and hub currencies.
Each entry names exactly one chain. Declare the same deployment twice if it runs on two chains.
nameis shown to the user asvia <name>once an exact-output swap is quoted. It defaults to the protocol.hubCurrenciesare the intermediate tokens tried for two-hop routes, usually wrapped native and the chain’s main stablecoin.feeTiers/tickSpacingsare the pool tiers to search. Include any non-standard tier your venue uses, such as PancakeSwap’s 2500.
Every venue covering a chain is quoted on every keystroke, and each one costs several quoter calls
against your RPC (roughly
feeTiers x (1 + hubCurrencies) per venue). Adding venues improves
fill and increases RPC load. Scope chainId tightly and keep hubCurrencies to the tokens that
actually carry liquidity.Venues from another protocol family
Most DEXs are forks of one of the three families above, so adding one is addresses only. A venue built on a different family — a Uniswap v2 pair, Curve, Balancer — needs an adapter inside the SDK, because the SDK owns the calldata rather than asking you to encode swaps yourself. Send us the chain, router, quoter and one funded pool and it becomes aprotocol every integration can name.
Theming
Set your app’s visual identity through thetheme prop. All SDK components inherit these values.
API URL Override
By default, the SDK connects to the Spicenet relayer. Override this if you’re proxying requests or using a custom deployment:Complete Provider Reference
Next Steps
Styling
Customize component appearance
Components
Explore available components
Examples
See complete examples
Best Practices
Security and integration patterns
