Skip to main content
For @spicenet-io/spiceflow-ui@4.10.0, connect your existing selector, amount input and button to useSpiceSupply. It is the same controller used by the stock SpiceSupply component. Your app defines the destination contract calls and renders the returned state. The SDK owns asset inventory, route selection, fee estimates, Max, funding, signing and transaction completion.

Provider Setup

Mount the provider stack once above this panel. Reuse your existing Privy, wagmi and Query providers. Set network="mainnet" explicitly for production; the default remains "testnet". SDK styles load automatically in the browser.

Complete Example

This panel deposits USDC into an ERC-4626 vault on Base. Pass the address of your vault, whose asset() must be Base USDC. For another protocol, replace only the destination token and the buildActionCalls body with that protocol’s ABI and calls.
The 4.10.0 controller receives four top-level inputs in this example: enabled, destinationToken, selectedAsset, and buildActionCalls. Only the first two token fields (chainId, address) are needed; symbol and decimals resolve from SDK metadata or the chain. Your selected asset and amount are UI state, while the vault address and its calls remain your protocol’s configuration. The default amount direction is "input"; choose another when your product needs it. enabled is lifecycle wiring, not a fee-readiness flag. Leave it true while fees load and use canExecute for the button. For a modal that stays mounted while hidden, pass enabled: isOpen. An upcoming SDK change defaults enabled to true, reducing this basic setup to three inputs; keep the explicit value with published 4.10.0. See the hook reference.

Amount Semantics

For Pay, use this same hook with amountDirection: "output" and paymentAmount. There is no separate useSpicePay hook. Use flow.submit() for the configured direction, render flow.fees.preview with its own symbol/decimals, and enable the action only when flow.canExecute. max() returns a fee-aware source amount string or null; never replace null with the full balance. buildActionCalls receives a raw bigint in destination-token units, including the protected minimum when routing requires a swap. Use that argument, not the source input text, to encode approvals and protocol calls. The builder can run during planning; it must not send transactions or write application state. Put post-transaction updates in an awaited onSuccess callback.

Wallets, Beneficiaries and Sources

Keep the selected Asset object intact. Key rows with assetPositionId(asset) and show wallet/location alongside token and chain: the same token can exist in multiple wallets or in Spice balance. Funding can come from either connected wallet by default, even when account mode chooses a different position owner. Use sourceChains, supportedSourceAssets, includeExternalWalletAssets, or includeCrossChainEmbeddedAssets only when your product needs a restriction. For a fixed protocol beneficiary, pass recipient and use ctx.beneficiary ?? ctx.userAddress in the action calls. ctx.executorAddress identifies the executing wallet; it can differ from the beneficiary. External mode with its matching destination token on the same chain executes directly through the SDK. Routed external sources fund the embedded execution wallet. A contract that credits only msg.sender cannot automatically credit a different beneficiary; constrain that action to a compatible source/executor rather than changing the recipient silently.

Completion and Errors

Render controller loading, fee, readiness and status fields directly. Keep balances visible during assets.refreshing; reserve the initial loader for assets.loading. onSubmit() is an optional notification after the SDK accepts a submission and before wallet prompts, not an execution override. Await app work in onSuccess, such as refreshing a position or recording access. If that work fails, retryFinalization() retries the application update without resending the confirmed transaction. The SDK does not persist an in-flight action journal or automatically resume a transaction after reload. Check on-chain balances and receipts before a new submission following an uncertain outcome.

Fee-Only Actions and Withdrawals

For a protocol action whose principal already sits in the executing wallet, use feeOnlyAction. Declare consumed tokens through actionInput and, if applicable, resulting funds through actionProceeds. The SDK chooses fee funding in input, proceeds, balance order by default; feeFunding can restrict that order. The builder must honor the amount it receives after any fee allocation. These are optional declarations for this action type, not requirements for ordinary Supply. SpiceWithdraw withdraws Spice balance, not a lending position. Protocol withdrawals use your protocol’s own calls with the controller. SpiceDeposit and SpiceWithdraw retain their separate callback contracts; do not migrate their callbacks as if they were Pay or Lock. See Hooks for the controller reference and Migration to 4.10.0 for the changes from manual integration.