跳至主要内容

Provider Hooks

Provider hooks 要求你的组件树被包裹在 OneProvider(或用于 Thirdweb 相关 hooks 的 OneThirdwebProvider)中。它们 仅支持 Web——即在浏览器中渲染的 React DOM 应用。

仅限 Web

OneProvider 外部调用任何 provider hook 将抛出:

Error: useOne must be used within a OneProvider

如需在 React Native 中使用 hooks,请改用独立 hooksAI 交易 hooks外汇 hooks

Provider 设置

在使用任何 provider hook 之前,请先包裹你的应用根节点:

import { OneProvider } from '@one_deploy/sdk';

function App() {
return (
<OneProvider
config={{
apiKey: process.env.NEXT_PUBLIC_ONE_API_KEY!,
projectId: process.env.NEXT_PUBLIC_ONE_PROJECT_ID!,
engineUrl: 'https://engine.one23.io', // optional, defaults to production
}}
>
<YourApp />
</OneProvider>
);
}

如果你还使用了 Thirdweb 钱包功能,请使用 OneThirdwebProvider 包裹:

import { OneThirdwebProvider } from '@one_deploy/sdk';

function App() {
return (
<OneThirdwebProvider
config={{
apiKey: process.env.NEXT_PUBLIC_ONE_API_KEY!,
projectId: process.env.NEXT_PUBLIC_ONE_PROJECT_ID!,
}}
thirdwebClientId={process.env.NEXT_PUBLIC_THIRDWEB_CLIENT_ID!}
>
<YourApp />
</OneThirdwebProvider>
);
}

useOne

主要的上下文 hook。返回完整的 SDK 上下文,包括配置、engine 客户端和当前认证状态。

签名

function useOne(): OneContextValue;

interface OneContextValue {
/** The OneEngineClient instance managed by the provider. */
engineClient: OneEngineClient;
/** Current SDK configuration. */
config: OneConfig;
/** Whether the SDK has finished initializing. */
isReady: boolean;
/** Current authenticated user, or null. */
user: OneUser | null;
/** Whether a user is currently authenticated. */
isAuthenticated: boolean;
}

用法

import { useOne } from '@one_deploy/sdk';

function Dashboard() {
const { engineClient, isReady, isAuthenticated, user } = useOne();

if (!isReady) return <p>Initializing SDK...</p>;

if (!isAuthenticated) return <p>Please sign in.</p>;

return (
<div>
<h1>Welcome, {user?.email}</h1>
<button
onClick={async () => {
const wallets = await engineClient.getUserWallets();
console.log(wallets);
}}
>
Load Wallets
</button>
</div>
);
}

useOneAuth

管理认证状态:登录、登出和会话信息。

签名

function useOneAuth(): OneAuthContextValue;

interface OneAuthContextValue {
/** The authenticated user object, or null. */
user: OneUser | null;
/** Whether a user session is active. */
isAuthenticated: boolean;
/** Whether an auth operation is in progress. */
isLoading: boolean;
/** Start an email OTP login flow. */
loginWithEmail: (email: string) => Promise<void>;
/** Verify the OTP code sent to the user's email. */
verifyEmailOtp: (email: string, otp: string) => Promise<OneUser>;
/** Start a wallet-signature login flow. */
loginWithWallet: (address: string, signature: string) => Promise<OneUser>;
/** Log the current user out and clear session tokens. */
logout: () => Promise<void>;
/** The current access token, or null. */
accessToken: string | null;
}

interface OneUser {
id: string;
email: string | null;
walletAddress: string | null;
createdAt: string;
}

用法

import { useOneAuth } from '@one_deploy/sdk';
import { useState } from 'react';

function LoginForm() {
const { loginWithEmail, verifyEmailOtp, isLoading, isAuthenticated, user } = useOneAuth();
const [email, setEmail] = useState('');
const [otp, setOtp] = useState('');
const [otpSent, setOtpSent] = useState(false);

if (isAuthenticated) {
return <p>Signed in as {user?.email}</p>;
}

const handleSendOtp = async () => {
await loginWithEmail(email);
setOtpSent(true);
};

const handleVerify = async () => {
const user = await verifyEmailOtp(email, otp);
console.log('Authenticated:', user.id);
};

return (
<div>
{!otpSent ? (
<>
<input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" />
<button onClick={handleSendOtp} disabled={isLoading}>Send OTP</button>
</>
) : (
<>
<input value={otp} onChange={(e) => setOtp(e.target.value)} placeholder="Enter OTP" />
<button onClick={handleVerify} disabled={isLoading}>Verify</button>
</>
)}
</div>
);
}

useOneWallet

提供钱包操作:列出钱包、选择活跃钱包以及余额数据。

签名

function useOneWallet(): OneWalletContextValue;

interface OneWalletContextValue {
/** All wallets belonging to the current user. */
wallets: Wallet[];
/** The currently selected (active) wallet. */
activeWallet: Wallet | null;
/** Set a wallet as the active wallet by address. */
setActiveWallet: (address: string) => void;
/** Aggregated USD balance of the active wallet. */
balance: string | null;
/** Whether wallets are being loaded. */
isLoading: boolean;
/** Error from the last wallet operation, or null. */
error: OneSDKError | null;
/** Refresh the wallet list and balances. */
refetch: () => Promise<void>;
}

interface Wallet {
address: string;
type: 'smart' | 'eoa';
chainId: number;
createdAt: string;
status: 'active' | 'pending_deployment';
}

用法

import { useOneWallet } from '@one_deploy/sdk';

function WalletSelector() {
const { wallets, activeWallet, setActiveWallet, balance, isLoading } = useOneWallet();

if (isLoading) return <p>Loading wallets...</p>;

return (
<div>
<h2>Active: {activeWallet?.address ?? 'None selected'}</h2>
<p>Balance: ${balance ?? '0.00'}</p>
<ul>
{wallets.map((w) => (
<li key={w.address}>
<button onClick={() => setActiveWallet(w.address)}>
{w.address} ({w.type}, chain {w.chainId})
</button>
</li>
))}
</ul>
</div>
);
}

useOneOnramp

管理法币入金操作:获取报价和创建购买会话。

签名

function useOneOnramp(): OneOnrampContextValue;

interface OneOnrampContextValue {
/** Fetch a quote for buying crypto with fiat. */
getQuote: (params: OnrampQuoteParams) => Promise<OnrampQuote>;
/** Create a payment session from a quote. */
createSession: (params: OnrampSessionRequest) => Promise<OnrampSession>;
/** The most recently fetched quote, or null. */
currentQuote: OnrampQuote | null;
/** Whether a quote or session request is in progress. */
isLoading: boolean;
/** Error from the last onramp operation, or null. */
error: OneSDKError | null;
}

interface OnrampQuoteParams {
fiatCurrency: string;
fiatAmount: number;
cryptoCurrency: string;
paymentMethod?: string;
}

用法

import { useOneOnramp } from '@one_deploy/sdk';

function BuyCrypto() {
const { getQuote, createSession, currentQuote, isLoading, error } = useOneOnramp();

const handleBuy = async () => {
const quote = await getQuote({
fiatCurrency: 'USD',
fiatAmount: 100,
cryptoCurrency: 'USDT',
paymentMethod: 'card',
});

const session = await createSession({
quoteId: quote.quoteId,
walletAddress: '0xAbc...',
chainId: 137,
});

// Redirect user to session.paymentUrl
window.location.href = session.paymentUrl!;
};

return (
<div>
<button onClick={handleBuy} disabled={isLoading}>Buy 100 USD of USDT</button>
{currentQuote && (
<p>Rate: 1 USD = {currentQuote.exchangeRate} USDT (fee: ${currentQuote.fee.amount})</p>
)}
{error && <p>Error: {error.message}</p>}
</div>
);
}

useOneSwap

管理代币兑换操作:获取报价、预览路由和执行兑换。

签名

function useOneSwap(): OneSwapContextValue;

interface OneSwapContextValue {
/** Fetch a swap quote. */
getQuote: (params: SwapQuoteParams) => Promise<SwapQuote>;
/** Execute a swap from a quote. */
executeSwap: (quoteId: string) => Promise<SwapTransaction>;
/** The most recently fetched swap quote, or null. */
currentQuote: SwapQuote | null;
/** Whether a swap operation is in progress. */
isLoading: boolean;
/** Error from the last swap operation, or null. */
error: OneSDKError | null;
}

interface SwapQuoteParams {
fromToken: string;
toToken: string;
amount: string;
chainId: number;
slippageBps?: number;
}

interface SwapQuote {
quoteId: string;
fromToken: string;
toToken: string;
fromAmount: string;
toAmount: string;
exchangeRate: number;
priceImpact: number;
route: string[];
estimatedGas: string;
expiresAt: string;
}

interface SwapTransaction {
transactionHash: string;
status: 'pending' | 'confirmed' | 'failed';
fromAmount: string;
toAmount: string;
}

用法

import { useOneSwap, CHAIN_IDS } from '@one_deploy/sdk';

function SwapPage() {
const { getQuote, executeSwap, currentQuote, isLoading, error } = useOneSwap();

const handleSwap = async () => {
const quote = await getQuote({
fromToken: 'ETH',
toToken: 'USDC',
amount: '0.5',
chainId: CHAIN_IDS.BASE,
slippageBps: 50, // 0.5%
});

console.log(`Swap 0.5 ETH -> ${quote.toAmount} USDC`);

const tx = await executeSwap(quote.quoteId);
console.log('Swap tx:', tx.transactionHash);
};

return (
<div>
<button onClick={handleSwap} disabled={isLoading}>Swap ETH to USDC</button>
{currentQuote && (
<p>
You receive: {currentQuote.toAmount} USDC
(impact: {currentQuote.priceImpact}%)
</p>
)}
{error && <p>Error: {error.message}</p>}
</div>
);
}

useOneTrading

通过 provider 上下文提供 AI 交易操作。这是独立 useAITrading hook 的 provider 版本。

签名

function useOneTrading(): OneTradingContextValue;

interface OneTradingContextValue {
/** Create a new AI trading order. */
createOrder: (params: CreateAIOrderParams) => Promise<AIOrder>;
/** Cancel an active order. */
cancelOrder: (orderId: string) => Promise<void>;
/** List orders for the current user. */
getOrders: (params?: AIOrderFilterParams) => Promise<AIOrder[]>;
/** Fetch portfolio summary. */
getPortfolio: () => Promise<AIPortfolioSummary>;
/** Whether a trading operation is in progress. */
isLoading: boolean;
/** Error from the last trading operation, or null. */
error: OneSDKError | null;
}

用法

import { useOneTrading } from '@one_deploy/sdk';

function TradingDashboard() {
const { getOrders, getPortfolio, isLoading } = useOneTrading();

const loadData = async () => {
const [orders, portfolio] = await Promise.all([
getOrders({ status: 'active' }),
getPortfolio(),
]);

console.log(`Active orders: ${orders.length}`);
console.log(`Total invested: $${portfolio.totalInvested}`);
};

return <button onClick={loadData} disabled={isLoading}>Load Trading Data</button>;
}

useOneEngine

从 provider 返回 OneEngineClient 实例。当你需要调用高级 hooks 未涵盖的原始 API 方法时使用此 hook。

签名

function useOneEngine(): OneEngineContextValue;

interface OneEngineContextValue {
/** The OneEngineClient instance, fully configured with auth. */
engineClient: OneEngineClient;
/** Whether the engine client has finished initialization. */
isReady: boolean;
}

用法

import { useOneEngine } from '@one_deploy/sdk';

function AdvancedOperations() {
const { engineClient, isReady } = useOneEngine();

if (!isReady) return <p>Initializing...</p>;

const handleDeploy = async () => {
// Access any of the 91+ OneEngineClient methods directly
const result = await engineClient.deployContract({
chainId: 8453,
bytecode: '0x...',
abi: [...],
constructorArgs: ['My Token', 'MTK'],
});

console.log('Deployed at:', result.contractAddress);
};

const handleBridge = async () => {
const quote = await engineClient.getBridgeQuote({
fromChainId: 1,
toChainId: 8453,
token: 'USDC',
amount: '1000',
});

console.log('Bridge fee:', quote.fee);
};

return (
<div>
<button onClick={handleDeploy}>Deploy Contract</button>
<button onClick={handleBridge}>Get Bridge Quote</button>
</div>
);
}

useThirdwebClient

OneThirdwebProvider 返回 Thirdweb 客户端实例。使用此 hook 可直接与 Thirdweb SDK 交互,进行高级钱包和合约操作。

签名

function useThirdwebClient(): ThirdwebClientContextValue;

interface ThirdwebClientContextValue {
/** The Thirdweb client instance. */
client: ThirdwebClient;
/** Whether the Thirdweb client is ready. */
isReady: boolean;
}

用法

import { useThirdwebClient } from '@one_deploy/sdk';

function ThirdwebExample() {
const { client, isReady } = useThirdwebClient();

if (!isReady) return <p>Loading Thirdweb...</p>;

return (
<div>
<p>Thirdweb client loaded. Client ID: {client.clientId}</p>
{/* Pass the client to other Thirdweb components or SDK calls */}
</div>
);
}
备注

useThirdwebClient 要求你的应用被包裹在 OneThirdwebProvider 中,而不是普通的 OneProvider。如果你使用的是不含 Thirdweb 的 OneProvider,此 hook 将抛出异常。


错误处理

所有 provider hooks 通过返回值中的 error 字段暴露错误。错误类型为 OneSDKError

interface OneSDKError {
code: string;
message: string;
details?: Record<string, unknown>;
}

常见错误码:

错误码含义
UNAUTHORIZED无活跃会话或 token 已过期
RATE_LIMITED请求过多——请在冷却后重试
INVALID_PARAMSAPI 调用的输入参数无效
NETWORK_ERROR无法连接到 ONE Engine API
NOT_FOUND请求的资源不存在
import { useOneSwap } from '@one_deploy/sdk';

function SwapWithErrorHandling() {
const { getQuote, error } = useOneSwap();

const handleQuote = async () => {
try {
await getQuote({ fromToken: 'ETH', toToken: 'USDC', amount: '1', chainId: 8453 });
} catch (err) {
// error is also available reactively via the hook return
console.error('Quote failed:', err);
}
};

return (
<div>
<button onClick={handleQuote}>Get Quote</button>
{error?.code === 'RATE_LIMITED' && <p>Too many requests. Please wait.</p>}
{error?.code === 'UNAUTHORIZED' && <p>Please sign in first.</p>}
</div>
);
}

另请参阅