/** * @octwa/sdk — Type Definitions (RFC-O-1 Compliant) * * Implements the Octra Provider JavaScript API as defined in RFC-O-1. */ interface OctraRequestArguments { readonly method: string; readonly params?: readonly unknown[] | object; } interface OctraProvider { readonly isOctra: true; readonly providerId?: string; readonly version?: string; request(args: OctraRequestArguments): Promise; on(event: OctraProviderEvent, listener: (...args: unknown[]) => void): OctraProvider; removeListener(event: OctraProviderEvent, listener: (...args: unknown[]) => void): OctraProvider; } interface OctraNetworkInfo { id: string; name: string; rpcUrl: string; explorerUrl?: string; supportsPrivacy: boolean; isTestnet: boolean; } type OctraPermission = 'read_address' | 'read_balance' | 'read_public_key' | 'sign_messages' | 'send_transactions' | 'contract_calls' | 'view_encrypted_balance' | 'encrypt_balance' | 'decrypt_balance' | 'private_transfers' | 'stealth_scan' | 'stealth_claim'; interface SendTransactionParams { to: string; amount: string; fee?: string; message?: string; } interface SignTransactionParams { to: string; amount: string; fee: string; nonce?: string; message?: string; } interface SignedOctraTransaction { from: string; to_: string; amount: string; nonce: number; ou: string; timestamp: number; op_type: string; signature: string; public_key: string; encrypted_data?: string; message?: string; } interface OctraTransactionResult { hash: string; accepted: boolean; status: 'pending' | 'confirmed' | 'rejected' | 'dropped'; nonce?: number; ouCost?: string; explorerUrl?: string; } interface CallContractParams { address: string; method: string; params?: unknown[]; caller?: string; } interface SendContractTransactionParams { address: string; method: string; params?: unknown[]; amount?: string; fee?: string; } interface EncryptedBalanceInfo { address: string; cipher?: string; cipherType?: string; decryptedAmount?: string; hasPvacPubkey: boolean; } interface PrivateTransferParams { to: string; amount: string; fee?: string; } interface SignMessageParams { message: string; address?: string; } interface SignMessageResult { address: string; publicKey: string; signature: string; } type OctraProviderEvent = 'connect' | 'disconnect' | 'networkChanged' | 'accountsChanged' | 'permissionsChanged' | 'balanceChanged' | 'transactionChanged' | 'message'; interface ConnectEventPayload { networkId: string; networkInfo: OctraNetworkInfo; } interface BalanceChangedPayload { address: string; public?: string; encrypted?: string; } interface TransactionChangedPayload { hash: string; status: 'pending' | 'confirmed' | 'rejected' | 'dropped'; receipt?: unknown; } interface ProviderMessage { type: string; data: unknown; } /** Standard RFC-O-1 error codes */ declare enum OctraErrorCode { UserRejected = 4001, Unauthorized = 4100, UnsupportedMethod = 4200, Disconnected = 4900, NetworkUnavailable = 4901 } /** Octra-specific error reasons (in error.data.reason) */ type OctraErrorReason = 'wallet_locked' | 'invalid_address' | 'invalid_amount' | 'invalid_nonce' | 'insufficient_balance' | 'fee_too_low' | 'staging_full' | 'duplicate_transaction' | 'invalid_signature' | 'proof_generation_failed' | 'privacy_not_supported' | 'recipient_view_pubkey_missing'; interface OctraSDKOptions { /** Timeout in ms to wait for provider detection (default: 3000) */ timeout?: number; /** Default permissions to request on connect */ defaultPermissions?: OctraPermission[]; } interface ConnectOptions { /** Permissions to request */ permissions?: OctraPermission[]; /** Target network ID */ networkId?: string; } interface WatchTransactionOptions { /** Total wait budget in ms (default: 120_000) */ timeoutMs?: number; /** Poll interval in ms (default: 3_000) */ pollIntervalMs?: number; /** Called on every poll tick */ onTick?: (status: OctraTransactionResult | null) => void; } declare global { interface Window { octra?: OctraProvider; /** * Multi-provider array per RFC-O-1 §"Provider Interface". * Every compliant wallet pushes its own provider object so dApps can * iterate when multiple wallets are installed in the same browser. */ octraProviders?: OctraProvider[]; } } /** * @octwa/sdk — EVM Types * * Type definitions for the EVM bridge surface. All amounts in ETH/token * smallest units unless otherwise noted. */ interface EvmNetworkInfo { id: string; name: string; chainId: number; symbol: string; explorerUrl?: string; rpcUrl?: string; } interface EvmBalanceResult { address: string; balance: string; balanceWei: string; chainId: number; } interface EvmTokenBalanceResult { token: string; owner: string; balance: string; } interface EvmTokenInfo { token: string; name: string; symbol: string; decimals: number; } interface EvmSendTransactionParams { to: string; /** Amount in ETH (decimal string, e.g. '0.1'). Omit or '0' for contract calls. */ value?: string; /** Hex-encoded calldata. */ data?: string; /** Gas limit override (decimal string). */ gasLimit?: string; } interface EvmTransactionResult { hash: string; chainId: number; } interface EvmTransferTokenParams { token: string; to: string; /** Amount in the token's smallest unit (e.g. for USDC with 6 decimals: '1000000' = 1 USDC). */ amount: string; } interface EvmApproveTokenParams { token: string; spender: string; /** Amount in smallest unit. Omit for unlimited (max uint256). */ amount?: string; } interface EvmAllowanceParams { token: string; owner: string; spender: string; } interface EvmAllowanceResult { allowance: string; } interface EvmSignMessageResult { signature: string; address: string; } interface EvmSignTypedDataParams { domain: Record; types: Record; value: Record; primaryType?: string; } interface EvmCallParams { to: string; data?: string; from?: string; value?: string; } interface EvmEstimateGasParams { to: string; data?: string; from?: string; value?: string; } interface EvmGasEstimate { gas: string; gasHex: string; } interface EvmGasPrice { gasPriceWei: string; gasPriceGwei: string; } /** * @octwa/sdk — EVM Bridge * * Typed wrapper for the evm_* methods exposed by OctWa. All signing happens * inside the wallet's trusted popup — the SDK never touches private keys. * * Usage: * const sdk = await OctraSDK.init(); * const addr = await sdk.evm.getDerivedAddress(); * const bal = await sdk.evm.getBalance(); */ declare class EvmBridge { private provider; private connected; /** @internal — instantiated by OctraSDK, not by consumers directly. */ constructor(provider: OctraProvider | null, isConnected: () => boolean); /** * Get the EVM address derived from the currently active Octra wallet. * No popup — the address is public data. */ getDerivedAddress(): Promise; /** Active EVM chain ID. */ getChainId(): Promise; /** Full network info for the active EVM chain. */ getNetworkInfo(): Promise; /** * Get the ETH (native) balance for an address. * Defaults to the derived EVM address when `address` is omitted. */ getBalance(address?: string, networkId?: string): Promise; /** Switch the active EVM chain. Opens a popup for user approval. */ switchChain(chainId: number): Promise; /** * Send an EVM transaction (native ETH transfer or arbitrary contract call). * Opens the wallet popup for user approval. */ sendTransaction(params: EvmSendTransactionParams): Promise; /** * Sign a plaintext message using `personal_sign`. * Opens the wallet popup for user approval. */ signMessage(message: string): Promise; /** * Sign EIP-712 structured data. * Opens the wallet popup for user approval. */ signTypedData(params: EvmSignTypedDataParams): Promise; /** * Get ERC-20 token balance. Defaults to derived address when `owner` is omitted. */ getTokenBalance(token: string, owner?: string): Promise; /** Get ERC-20 token metadata (name, symbol, decimals). */ getTokenInfo(token: string): Promise; /** * Transfer ERC-20 tokens. Opens the wallet popup for approval. * Amount is in the token's smallest unit. */ transferToken(params: EvmTransferTokenParams): Promise; /** * Approve a spender to transfer tokens on your behalf. * Opens the wallet popup for approval. Omit `amount` for unlimited. */ approveToken(params: EvmApproveTokenParams): Promise; /** Check the current ERC-20 allowance. No popup. */ getAllowance(params: EvmAllowanceParams): Promise; /** Execute a read-only `eth_call`. No popup, no transaction. */ call(params: EvmCallParams): Promise; /** Estimate gas for a transaction. */ estimateGas(params: EvmEstimateGasParams): Promise; /** Get current gas price. */ getGasPrice(): Promise; private request; private ensureConnected; } /** * @octwa/sdk — Main SDK Class (RFC-O-1 Compliant) * * Thin, ergonomic wrapper around window.octra.request(). * All methods map directly to RFC-O-1 provider methods. */ declare class OctraSDK { private provider; private accounts; private connected; /** EVM bridge — access via `sdk.evm.*`. Lazily initialized on first access. */ private _evm; private constructor(); /** * Initialize the SDK. Detects the provider (window.octra) or times out. */ static init(options?: OctraSDKOptions): Promise; /** * EVM bridge — typed access to all evm_* methods. * The bridge is lazy-initialized and shares the same provider session. */ get evm(): EvmBridge; /** Check if the Octra wallet extension is installed. */ isInstalled(): boolean; /** Check if the dApp is connected (has exposed accounts). */ isConnected(): boolean; /** Get the raw provider for advanced usage. */ getProvider(): OctraProvider | null; /** Get currently exposed accounts. */ getAccounts(): string[]; /** * Request access to wallet accounts (octra_requestAccounts). * Opens a popup for user consent. */ connect(options?: ConnectOptions): Promise; /** * Get accounts currently exposed to this dApp (octra_accounts). * Returns empty array if not authorized. */ fetchAccounts(): Promise; /** * Revoke this dApp's session (octra_disconnect). * * Removes the connection from the wallet's `connectedDApps` map and * clears any per-origin EVM chain override. The next `connect()` call * will trigger a fresh approval popup, letting the user pick a * different wallet if needed. * * Local SDK state is also reset, so `isConnected()` returns false * immediately even if the wallet's `disconnect` event has not yet * propagated back through the message bridge. */ disconnect(): Promise; /** Get the active network ID (octra_networkId). */ getNetworkId(): Promise; /** Get full network info (octra_networkInfo). */ getNetworkInfo(): Promise; /** Get permissions granted to this dApp (octra_permissions). */ getPermissions(): Promise; /** Request a network switch (octra_switchNetwork). */ switchNetwork(networkId: string): Promise; /** * Sign an arbitrary message (octra_signMessage). * Requires sign_messages permission. Opens popup. */ signMessage(message: string, address?: string): Promise; /** * Create, sign, and submit a transaction (octra_sendTransaction). * Requires send_transactions permission. Opens popup. */ sendTransaction(params: SendTransactionParams): Promise; /** * Sign a transaction without submitting (octra_signTransaction). * Requires send_transactions permission. Opens popup. */ signTransaction(params: SignTransactionParams): Promise; /** * Submit a pre-signed transaction (octra_submitTransaction). * Requires send_transactions permission. */ submitTransaction(tx: SignedOctraTransaction): Promise; /** * Execute a read-only contract call (octra_callContract). * Maps to native RPC contract_call. No permission required. */ callContract(params: CallContractParams): Promise; /** * Send a contract transaction (octra_sendContractTransaction). * Requires contract_calls permission. Opens popup. */ sendContractTransaction(params: SendContractTransactionParams): Promise; /** * Get a contract execution receipt (octra_getContractReceipt). */ getContractReceipt(hash: string): Promise; /** * Get encrypted balance info (octra_getEncryptedBalance). * Requires view_encrypted_balance permission. */ getEncryptedBalance(address?: string): Promise; /** * Encrypt public balance into private (octra_encryptBalance). * Requires encrypt_balance permission. Opens popup. */ encryptBalance(amount: string, fee?: string): Promise; /** * Decrypt private balance into public (octra_decryptBalance). * Requires decrypt_balance permission. Opens popup. */ decryptBalance(amount: string, fee?: string): Promise; /** * Send a private transfer (octra_sendPrivateTransfer). * Requires private_transfers permission. Opens popup. */ sendPrivateTransfer(params: PrivateTransferParams): Promise; /** * Scan stealth outputs (octra_scanStealth). * Requires stealth_scan permission. */ scanStealth(fromEpoch?: number): Promise; /** * Claim a stealth output (octra_claimStealth). * Requires stealth_claim permission. Opens popup. */ claimStealth(outputId: string, fee?: string): Promise; /** * Call any native Octra RPC method directly. * Uses positional array params as per Octra JSON-RPC. * * @example * const balance = await sdk.rpc('octra_balance', ['oct...']); * const epoch = await sdk.rpc('epoch_current'); */ rpc(method: string, params?: unknown[]): Promise; /** * Poll until a transaction reaches a terminal state. * Resolves with the final status or rejects on timeout. */ waitForConfirmation(hash: string, options?: WatchTransactionOptions): Promise; /** * Subscribe to provider events. */ on(event: OctraProviderEvent, listener: (...args: unknown[]) => void): this; /** * Unsubscribe from provider events. */ removeListener(event: OctraProviderEvent, listener: (...args: unknown[]) => void): this; private request; private ensureInstalled; private ensureConnected; } /** * @octwa/sdk — Error Classes (RFC-O-1 Compliant) * * Standard error codes: * 4001 — User rejected * 4100 — Unauthorized * 4200 — Unsupported method * 4900 — Disconnected * 4901 — Network unavailable */ declare class OctraProviderError extends Error { readonly code: number; readonly data?: { reason?: OctraErrorReason; [key: string]: unknown; }; constructor(code: number, message: string, reason?: OctraErrorReason); } declare class UserRejectedError extends OctraProviderError { constructor(message?: string); } declare class UnauthorizedError extends OctraProviderError { constructor(message?: string, reason?: OctraErrorReason); } declare class UnsupportedMethodError extends OctraProviderError { constructor(method: string); } declare class DisconnectedError extends OctraProviderError { constructor(message?: string); } declare class NetworkUnavailableError extends OctraProviderError { constructor(networkId?: string); } declare class NotInstalledError extends OctraProviderError { constructor(); } declare class TimeoutError extends OctraProviderError { constructor(operation?: string); } /** * Check if an error is a user rejection (code 4001). */ declare function isUserRejection(error: unknown): boolean; /** * Wrap a raw provider error into a typed OctraProviderError. * * Maps each RFC-O-1 standard code onto its dedicated subclass so * downstream code can do `err instanceof UnauthorizedError` rather * than checking `.code` manually. Falls back to the base class only * for non-standard codes. */ declare function wrapProviderError(error: unknown): OctraProviderError; /** * @octwa/sdk — Utility Functions * * Provider detection follows RFC-O-1 §"Provider Discovery": * * 1. The announce handshake (`octra:announceProvider` / * `octra:requestProvider`) is the canonical way to identify a * wallet. We listen first and only fall back to globals after a * grace window. * 2. `window.octraProviders` is the multi-provider array — every * compliant wallet pushes its own provider object. We prefer it * over `window.octra` because the latter is a single slot that * can be overwritten by whichever extension loads last. * 3. `window.octra` is the legacy single-provider fallback. It works * for dApps that only expect one wallet, but cannot disambiguate * when multiple wallets coexist. * * When multiple OctraProviders are reachable, the SDK prefers the one * whose `providerId === 'octwa'`. dApps that want to surface every * wallet should consume `octra:announceProvider` directly. */ /** * Get the Octra provider from window if available. * Prefers OctWa over any other RFC-O-1 wallet that may be installed. */ declare function getProvider(): OctraProvider | null; /** Synchronous check — is a compatible provider already injected? */ declare function isProviderInstalled(): boolean; /** * Wait for the provider to be injected. * * Uses RFC-O-1's announce/request handshake first, then falls back to * `window.octraProviders` / `window.octra` polling. The announce path * is preferred because it returns the *correct* provider object even * when another wallet has overwritten `window.octra`. */ declare function detectProvider(timeout?: number): Promise; export { type BalanceChangedPayload, type CallContractParams, type ConnectEventPayload, type ConnectOptions, DisconnectedError, type EncryptedBalanceInfo, type EvmAllowanceParams, type EvmAllowanceResult, type EvmApproveTokenParams, type EvmBalanceResult, EvmBridge, type EvmCallParams, type EvmEstimateGasParams, type EvmGasEstimate, type EvmGasPrice, type EvmNetworkInfo, type EvmSendTransactionParams, type EvmSignMessageResult, type EvmSignTypedDataParams, type EvmTokenBalanceResult, type EvmTokenInfo, type EvmTransactionResult, type EvmTransferTokenParams, NetworkUnavailableError, NotInstalledError, OctraErrorCode, type OctraErrorReason, type OctraNetworkInfo, type OctraPermission, type OctraProvider, OctraProviderError, type OctraProviderEvent, type OctraRequestArguments, OctraSDK, type OctraSDKOptions, type OctraTransactionResult, type PrivateTransferParams, type ProviderMessage, type SendContractTransactionParams, type SendTransactionParams, type SignMessageParams, type SignMessageResult, type SignTransactionParams, type SignedOctraTransaction, TimeoutError, type TransactionChangedPayload, UnauthorizedError, UnsupportedMethodError, UserRejectedError, type WatchTransactionOptions, detectProvider, getProvider, isProviderInstalled, isUserRejection, wrapProviderError };