Skip to main content
This guide targets stable @spicenet-io/spiceflow-ui@4.19.0. Keep your app’s layout and wallet-provider stack; update its SDK contracts and status handling. The package depends on spiceflow-core@0.8.2. If your app imports core directly, align that dependency rather than keeping a second, older core API.

Migration Map

Basic Action Setup

A selected-asset Supply controller needs destinationToken, selectedAsset, and buildActionCalls. The destination needs chainId and address; metadata resolves automatically. The app owns protocol addresses, ABIs, beneficiary selection and application updates. The SDK owns inventory, conversion, funding, fees, Max and execution. See the complete example. Use "input" for principal plus fees, "input-inclusive" for a total source budget, and "output" for a fixed destination payment. Lock uses input-inclusive. Builder amounts are destination-token bigints, not source-token units. Show fees using the SDK’s returned currency and decimals. Keep network="mainnet" explicit for production; the default is testnet. nativeChainId remains the app-chain setting for account deposits and withdrawals. A client rpcOverrides entry wins; otherwise SDK reads use the built-in endpoint. Wagmi transports alone do not configure SDK reads.

Cash and Scheduled Actions

  • combineSourceBalances is opt-in and combines eligible matching wallet and escrow positions.
  • fundingSources supports a native account purchase from nominated positions, with conversions and fees inside a budget denominated in the destination chain’s supported USDC. It requires 7702 mode, selectedAsset: null, and input-inclusive semantics. See Cash funding.
  • useSpiceLimitOrders prepares, signs, places and manages supported limit orders. Its optional combined-balance mode can fund an escrow shortfall from the account wallet.
  • useSpiceConditionalIntents prepares fixed actions or supported swaps, collects signatures, and registers them with a configured conditional-intent service and evaluator. These are separate interfaces in this release. See Conditional intents and limit orders.
SDK exports alone do not establish that a custom backend supports these services. Use the configured API’s supported capabilities; do not replace an unavailable service with a host execution loop.

Wallets and Callers

Matching-token external actions on the destination chain execute directly through the SDK, with native gas paid by that wallet. Calls are sequential, not atomic. This path excludes fee-only, proceeds-funded and zero-amount payments. By default, routed sources use the embedded execution wallet. A protocol that credits only msg.sender must execute from the intended owner’s wallet; setting recipient does not change that contract behavior. For a routed action that must execute from the connected external wallet, useSpiceSupply accepts actionExecution: { wallet: "external", recoveryKey: "your-action-key" }. The SDK owns funding and then sends the destination calls from that wallet. This requires a positive ERC-20 Supply/Pay action, a ready external signer, and explicit rpcOverrides for the destination and any wallet-source chain. It does not support fee-only actions, proceeds funding, native destination tokens or prependSourceEscrow. This hook option is separate from the deprecated onPayExecute override. Do not implement a second host transaction sender around it.

Recovery and Completion

The configured backend can automatically continue accepted actions when it advertises that capability. The SDK observes existing action/step status and exposes status.actionId, status.intentId, status.autoContinue, status.pending, status.recoveryChecking and status.recoveryError. An unresolved submission can expose status.submissionStatus === "unknown" and its submission identity. Use refreshStatus() to reconcile it, and use canExecute rather than bypassing the controller’s readiness. Closing a modal, hiding a tab, or losing an HTTP response does not cancel an accepted action. This is backend recovery, not a persisted browser action journal. A reload does not guarantee replay of an application’s previous success callback. Reload application state from authoritative records. Direct sequential external-wallet calls also do not gain durable browser progress; inspect receipts before retrying a partially completed sequence. Supply/Pay verifies the final destination receipt and reports that transaction hash. It can finish the user-facing destination action while later backend settlement continues. A source funding hash is not the destination result. Account deposits still require their relevant Spice-credit checks. The controller awaits onSuccess / onLockSuccess. If only the application update fails, retryFinalization() retries that update without resending funds. Confirmed results remain associated with the submitted action while inputs change or a mounted form is hidden. Keep callback handling idempotent and separate application errors from transaction failures. Accepted immediate-action plans have no arbitrary UI timer expiry; changed inputs or invalid funding still require a valid plan. Scheduled orders and conditional authorizations have their own explicit expiry and trigger-freshness contracts.

Upgrade Checks

  1. Build against the published package and its peer dependency ranges.
  2. Verify source identity with assetPositionId; retain owner, location, chain and raw token units.
  3. Check amount modes, combined balances if enabled, Max, fee currency and insufficient funds.
  4. Verify direct and routed execution for your contract’s caller and beneficiary semantics.
  5. Check pending/unknown submissions, status-refresh failure and application-finalization retry.
  6. For scheduled actions, review the exact fixed calls, budget, minimum output, expiry and signatures before registration. Verify service support and cancellation behavior on your configured backend.
Deposit and Withdraw retain their distinct callback contracts. Do not apply the Pay/Lock override migration to account deposit/withdraw callbacks.