import { ResultAsync } from 'neverthrow'; import { Address, WalletClient, TransactionReceipt } from 'viem'; import { z } from 'zod'; /** * Minimal viem PublicClient interface — consumers pass their own client. * The SDK uses `readContract` for single reads and `multicall` where available * to batch multiple reads into one RPC round-trip. */ interface PublicClientLike { readContract(args: { address: Address; abi: readonly unknown[]; functionName: string; args: readonly unknown[]; }): Promise; multicall?(args: { contracts: readonly { address: Address; abi: readonly unknown[]; functionName: string; args?: readonly unknown[]; }[]; allowFailure?: boolean; }): Promise; } declare class SdkError extends Error { readonly code: TCode; readonly cause?: unknown; readonly context?: Record; constructor(message: string, options: { code: TCode; cause?: unknown; context?: Record; }); } type StakeErrorCode = "VALIDATION_ERROR" | "CONTRACT_READ_ERROR" | "TX_SUBMISSION_FAILED" | "RECEIPT_TIMEOUT" | "TX_REVERTED"; declare class StakeError extends SdkError { constructor(message: string, options: { code: StakeErrorCode; cause?: unknown; context?: Record; }); } declare const ZodGetUserStakeParamsSchema: z.ZodObject<{ user: z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>; }, z.core.$strip>; type GetUserStakeParams = z.infer; declare const ZodGetStakeBoostConfigParamsSchema: z.ZodObject<{ currency: z.ZodEnum<{ IDR: "IDR"; INR: "INR"; BRL: "BRL"; ARS: "ARS"; MEX: "MEX"; VEN: "VEN"; BOB: "BOB"; EUR: "EUR"; NGN: "NGN"; USD: "USD"; COP: "COP"; CUP: "CUP"; ECU: "ECU"; PEN: "PEN"; PHP: "PHP"; }>; }, z.core.$strip>; type GetStakeBoostConfigParams = z.infer; declare const ZodGetP2pTokenBalanceParamsSchema: z.ZodObject<{ address: z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>; }, z.core.$strip>; type GetP2pTokenBalanceParams = z.infer; declare const ZodStakeParamsSchema: z.ZodObject<{ tokens: z.ZodBigInt; }, z.core.$strip>; type StakeParams = z.infer; declare const ZodTopUpParamsSchema: z.ZodObject<{ tokens: z.ZodBigInt; }, z.core.$strip>; type TopUpParams = z.infer; interface StakeConfig { readonly publicClient: PublicClientLike; readonly diamondAddress: Address; readonly p2pTokenAddress: Address; } /** * Stake lifecycle state for a user. * 0 — None: no active stake. * 1 — Active: stake is live. * 2 — CooldownRequested: unstake requested; awaiting cooldown end. * 3 — Seized: stake was forcefully seized. */ type StakeStatus = "none" | "active" | "cooldown" | "seized"; /** Normalized on-chain stake record for a user. */ interface UserStake { /** Currently staked token amount (raw bigint, token decimals). */ readonly stakedAmount: bigint; /** Unix seconds when cooldown ends (0 if not in cooldown). */ readonly cooldownEnd: bigint; /** Lifecycle status decoded from the on-chain enum. */ readonly status: StakeStatus; } /** Raw tuple returned by `getUserStake` before normalization. */ interface RawUserStake { readonly stakedAmount: bigint; readonly cooldownEnd: bigint; readonly status: number; } /** * Per-currency boost config — how many tokens map to 1 USD of boost, and the * cap on USD-denominated boost a stake can unlock. */ interface StakeBoostConfig { readonly tokensPerUsdNumerator: bigint; readonly tokensPerUsdDenominator: bigint; readonly maxBoostUsd: bigint; } /** Global stake boost configuration shared across all users. */ interface StakeBoostGlobals { readonly p2pToken: Address; readonly fraudReserve: Address; readonly maxStakeTokens: bigint; readonly normalCooldown: bigint; readonly blacklistCooldown: bigint; readonly tokenDecimals: number; readonly totalStaked: bigint; } /** Raw tuple returned by `getStakeBoostGlobals` before normalization. */ type RawStakeBoostGlobals = readonly [ Address, Address, bigint, bigint, bigint, number, bigint ]; interface PreparedTx { readonly to: `0x${string}`; readonly data: `0x${string}`; readonly value: bigint; } interface TxResult { readonly hash: `0x${string}`; readonly receipt?: TransactionReceipt; } interface ExecuteBase { readonly walletClient: WalletClient; readonly waitForReceipt?: boolean; } interface CancelUnstakeAction { prepare(): ResultAsync; execute(params: ExecuteBase): ResultAsync; } interface ClaimUnstakeAction { prepare(): ResultAsync; execute(params: ExecuteBase): ResultAsync; } interface RequestUnstakeAction { prepare(): ResultAsync; execute(params: ExecuteBase): ResultAsync; } interface StakeAction { prepare(params: StakeParams): ResultAsync; execute(params: StakeParams & ExecuteBase): ResultAsync; } interface TopUpAction { prepare(params: TopUpParams): ResultAsync; execute(params: TopUpParams & ExecuteBase): ResultAsync; } interface StakeClient { /** Reads the on-chain stake record for a user (stakedAmount, cooldownEnd, status). */ getUserStake(params: GetUserStakeParams): ResultAsync; /** Reads the per-currency stake boost config (tokens-per-USD, max boost). */ getStakeBoostConfig(params: GetStakeBoostConfigParams): ResultAsync; /** Reads global stake boost configuration (token addr, cooldowns, totals). */ getStakeBoostGlobals(): ResultAsync; /** Reads the P2P token (ERC20) balance for a given address (raw bigint). */ getP2pTokenBalance(params: GetP2pTokenBalanceParams): ResultAsync; readonly stake: StakeAction; readonly topUp: TopUpAction; readonly requestUnstake: RequestUnstakeAction; readonly cancelUnstake: CancelUnstakeAction; readonly claimUnstake: ClaimUnstakeAction; } /** * Creates the P2P token stake client — exposes a read for the user's stake and * prepare/execute write pairs for stake, topUp, requestUnstake, and claimUnstake. */ declare function createStake(config: StakeConfig): StakeClient; export { type ExecuteBase, type GetP2pTokenBalanceParams, type GetStakeBoostConfigParams, type GetUserStakeParams, type PreparedTx, type RawStakeBoostGlobals, type RawUserStake, type StakeBoostConfig, type StakeBoostGlobals, type StakeClient, type StakeConfig, StakeError, type StakeErrorCode, type StakeParams, type StakeStatus, type TopUpParams, type TxResult, type UserStake, createStake };