useWallet
Access wallet connection state and actions from any component withinSpiceFlowProvider.
Usage
Copy
import { useWallet } from "@spicenet-io/spiceflow";
function MyComponent() {
const { address, isConnected, isAuthenticated, actions } = useWallet();
return (
<div>
{isConnected ? (
<p>Connected: {address}</p>
) : (
<button onClick={() => actions.login()}>Connect</button>
)}
</div>
);
}
Return Value
Copy
interface UseWalletReturn {
// State
isReady: boolean;
isAuthenticated: boolean;
isConnected: boolean;
address: string | undefined;
provider: 'privy' | 'dynamic' | 'para' | null;
// Actions
actions: {
login: () => Promise<void>;
logout: () => Promise<void>;
signMessage: (message: string | { raw: Hex }) => Promise<{ signature: string }>;
signAuthorization: (params: {
contractAddress: Address;
chainId: number;
nonce: number;
}) => Promise<Authorization>;
};
}
Examples
Copy
function ConnectionStatus() {
const { isConnected, address } = useWallet();
return (
<div>
{isConnected ? (
<span>✓ Connected: {address?.slice(0, 6)}...{address?.slice(-4)}</span>
) : (
<span>⚠ Not connected</span>
)}
</div>
);
}
useAssets
Fetch and manage user assets across multiple chains.Usage
Copy
import { useAssets, fetchBalances } from "@spicenet-io/spiceflow";
function AssetList() {
const { address } = useWallet();
const { assets, loading, error, refreshAssets } = useAssets({
address,
supportedChains: [11155111, 1551],
fetchBalances
});
if (loading) return <p>Loading assets...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{assets.map(asset => (
<li key={`${asset.chainId}-${asset.address}`}>
{asset.symbol}: {asset.balanceFormatted} on Chain {asset.chainId}
</li>
))}
</ul>
);
}
Config
Copy
interface UseAssetsConfig {
address: string | undefined;
supportedChains: number[];
fetchBalances: (address: string, chainIds: number[]) => Promise<Asset[]>;
}
Return Value
Copy
interface UseAssetsReturn {
assets: Asset[];
loading: boolean;
error: string | null;
refreshAssets: () => Promise<void>;
}
interface Asset {
address: string;
symbol: string;
name: string;
decimals: number;
chainId: number;
balance: bigint;
balanceFormatted: number;
isNative: boolean;
logoUrl?: string;
}
Example with Refresh
Copy
function AssetManager() {
const { address } = useWallet();
const { assets, refreshAssets, loading } = useAssets({
address,
supportedChains: [11155111, 1551],
fetchBalances
});
return (
<div>
<button onClick={refreshAssets} disabled={loading}>
{loading ? "Refreshing..." : "Refresh Assets"}
</button>
<AssetList assets={assets} />
</div>
);
}
useStatus
Track the status of cross-chain transaction execution.Usage
Copy
import { useStatus, checkStepStatus } from "@spicenet-io/spiceflow";
function TransactionStatus() {
const { intentStatus, startStatusPolling, clearStatus } = useStatus({
checkStepStatus
});
if (!intentStatus) return null;
return (
<div>
<h3>Transaction Status</h3>
{intentStatus.steps.map((step, index) => (
<div key={index}>
Step {index}: {step.status}
{step.transactionHash && (
<a href={`https://etherscan.io/tx/${step.transactionHash}`}>
View on Explorer
</a>
)}
</div>
))}
<button onClick={clearStatus}>Close</button>
</div>
);
}
Config
Copy
interface UseStatusConfig {
checkStepStatus: (intentId: string, stepId: number) => Promise<StepStatusResponse>;
}
Return Value
Copy
interface UseStatusReturn {
intentStatus: IntentStatus | null;
startStatusPolling: (intentId: string, initialSteps: IntentStep[]) => void;
clearStatus: () => void;
}
interface IntentStatus {
intentId: string;
steps: IntentStep[];
currentStepIndex: number;
isComplete: boolean;
hasError: boolean;
}
interface IntentStep {
stepId: number;
chainId: number;
chainName: string;
status: 'created' | 'executing' | 'success' | 'error' | 'reverted';
transactionHash?: string;
error?: string;
}
Example with Polling
Copy
function SwapWithStatus() {
const { startStatusPolling } = useStatus({ checkStepStatus });
const [isExecuting, setIsExecuting] = useState(false);
const handleSwap = async () => {
setIsExecuting(true);
try {
// Execute swap and get intentId
const result = await executeSwap();
// Start polling for status
startStatusPolling(result.intentId, [
{ stepId: 0, chainId: 11155111, chainName: "Sepolia", status: "created" },
{ stepId: 1, chainId: 1551, chainName: "Citrea", status: "created" }
]);
} finally {
setIsExecuting(false);
}
};
return (
<button onClick={handleSwap} disabled={isExecuting}>
{isExecuting ? "Executing..." : "Execute Swap"}
</button>
);
}
useFromInput
Control the “from” asset input in swap UIs.Usage
Copy
import { useFromInput } from "@spicenet-io/spiceflow";
function CustomSwapInput() {
const { fromAmount, setFromAmount } = useFromInput('');
return (
<input
type="text"
value={fromAmount}
onChange={(e) => setFromAmount(e.target.value)}
placeholder="Enter amount"
/>
);
}
Return Value
Copy
interface UseFromInputReturn {
fromAmount: string;
setFromAmount: (amount: string) => void;
}
Example with SwapWidget
Copy
function App() {
const fromInputHook = useFromInput('');
return (
<SwapWidget
swapBatches={[]}
supportedChains={[11155111]}
fromInputHook={fromInputHook}
/>
);
}
useToInputUpdate
Control the “to” asset input in swap UIs.Usage
Copy
import { useToInputUpdate } from "@spicenet-io/spiceflow";
function CustomSwapOutput() {
const { toAmount, setToAmount } = useToInputUpdate('');
return (
<input
type="text"
value={toAmount}
onChange={(e) => setToAmount(e.target.value)}
placeholder="Receive amount"
/>
);
}
Return Value
Copy
interface UseToInputUpdateReturn {
toAmount: string;
setToAmount: (amount: string) => void;
}
