UNPKG

@keyban/sdk-base

Version:

Keyban Javascript SDK provides core functionalities for the MPC wallet solution, supporting web and Node.js apps with TypeScript, custom storage, and Ethereum blockchain integration.

427 lines (328 loc) 11 kB
# Keyban JavaScript SDK The official JavaScript SDK for Keyban's Wallet as a Service (WaaS). Integrate secure MPC wallets into your JavaScript or Node.js applications with support for multiple blockchains, NFTs, tokens, and advanced features like Digital Product Passports and loyalty programs. ## Installation ```bash npm install @keyban/sdk-base @keyban/types ``` ## Quick Start ```typescript import { KeybanClient, Network } from "@keyban/sdk-base"; // Initialize the client const client = new KeybanClient({ appId: "your-app-id", network: Network.PolygonAmoy, }); // Get an account const account = await client.initialize(); console.log("Address:", account.address); // Transfer native currency const txHash = await account.transfer( "0xRecipientAddress", 1_000_000_000_000_000_000n // 1 token in wei ); ``` ## Key Features - **Multi-Blockchain Support** - EVM (Ethereum, Polygon), Starknet, Stellar - **MPC Security** - Non-custodial wallets with threshold signatures - **NFT & Token Support** - ERC-20, ERC-721, ERC-1155, Soroban tokens - **Digital Product Passports** - Claim and manage tokenized products - **Loyalty Programs** - Points, rewards, wallet pass integration - **GraphQL API** - Real-time subscriptions for balances and transfers - **TypeScript-First** - Full type safety with `@keyban/types` - **Custom Storage** - Flexible client share persistence ## Blockchain Support | Feature | EVM (Ethereum, Polygon) | Starknet | Stellar | |---------|------------------------|----------|---------| | Native Transfers | ETH, POL | STRK | XLM | | ERC-20 Tokens | | 🚧 | Soroban | | NFTs (ERC-721/1155) | | 🚧 | 🚧 | | Message Signing | Hex | String[] | Base64 | | Fee Estimation | EIP-1559 | | Stroops | | Networks | Anvil, Amoy | Devnet, Sepolia, Mainnet | Quickstart, Testnet, Mainnet | ## Core Operations ### Initialize Account ```typescript const account = await client.initialize(); console.log({ address: account.address, publicKey: account.publicKey, accountId: account.accountId, }); ``` ### Sign Message ```typescript // EVM - returns hex string const signature = await account.signMessage("Hello, Keyban!"); // Stellar - returns base64 string const signature = await stellarAccount.signMessage("Hello, Keyban!"); // Starknet - returns string array const signatures = await starknetAccount.signMessage("Hello, Keyban!"); ``` ### Transfer Native Currency ```typescript // Estimate fees first const fees = await account.estimateTransfer("0xRecipient"); console.log("Estimated fees:", fees); // Perform transfer const txHash = await account.transfer( "0xRecipient", 1_000_000_000_000_000_000n, // Amount in smallest unit (wei) fees // Optional: use custom fees ); ``` ### Transfer ERC-20 Tokens ```typescript const txHash = await account.transferERC20({ contractAddress: "0xTokenContract", to: "0xRecipient", value: 1_000_000n, // 1 USDC (6 decimals) }); ``` ### Transfer NFTs ```typescript // ERC-721 await account.transferNft({ contractAddress: "0xNftContract", to: "0xRecipient", tokenId: "123", standard: "ERC721", }); // ERC-1155 await account.transferNft({ contractAddress: "0xNftContract", to: "0xRecipient", tokenId: "456", standard: "ERC1155", value: 5n, // Transfer 5 copies }); ``` ## GraphQL Queries The SDK provides pre-built GraphQL documents for querying blockchain data. ### Query Token Balances ```typescript import { walletTokenBalancesDocument } from "@keyban/sdk-base/graphql"; const { data } = await client.apolloClient.query({ query: walletTokenBalancesDocument, variables: { walletId: account.address, first: 20, }, }); console.log("Token balances:", data.wallet.tokenBalances.nodes); ``` ### Query NFTs ```typescript import { walletNftsDocument } from "@keyban/sdk-base/graphql"; const { data } = await client.apolloClient.query({ query: walletNftsDocument, variables: { walletId: account.address, first: 20, }, }); console.log("NFTs:", data.wallet.nftBalances.nodes); ``` ### Real-Time Subscriptions ```typescript import { tokenBalancesSubscriptionDocument } from "@keyban/sdk-base/graphql"; const subscription = client.apolloClient.subscribe({ query: tokenBalancesSubscriptionDocument, variables: { walletId: account.address }, }).subscribe({ next: ({ data }) => { console.log("Balance updated:", data.tokenBalances); }, error: (err) => console.error("Subscription error:", err), }); // Don't forget to unsubscribe when done subscription.unsubscribe(); ``` ### Query Transfer History ```typescript import { walletAssetTransfersDocument } from "@keyban/sdk-base/graphql"; const { data } = await client.apolloClient.query({ query: walletAssetTransfersDocument, variables: { walletId: account.address, first: 50, }, }); console.log("Transaction history:", data.wallet.assetTransfers.nodes); ``` ## Digital Product Passports (DPP) Claim tokenized products using the DPP service. ```typescript // Claim a product with authentication const result = await client.api.dpp.claim({ productId: "product-uuid", password: "product-password", }); // Magic claim (passwordless) const result = await client.api.dpp.magicClaim({ productId: "product-uuid", magicToken: "magic-token-uuid", }); // Get product details const product = await client.api.dpp.getProduct("product-uuid"); console.log("Product:", product.name, product.status); ``` ## Loyalty Programs Access loyalty points, rewards, and wallet passes. ```typescript // Get loyalty balance const balance = await client.api.loyalty.getBalance(); console.log("Points:", balance.points); // Get reward tiers const tiers = await client.api.loyalty.getRewardTiers(); console.log("Available rewards:", tiers); // Add to Apple/Google Wallet const passUrl = await client.api.loyalty.addToWalletPass("google"); window.open(passUrl, "_blank"); ``` ## Balance Formatting ```typescript import { formatBalance } from "@keyban/sdk-base"; const balance = { raw: 1_500_000_000_000_000_000n, decimals: 18, symbol: "ETH", isNative: true, }; const formatted = formatBalance(client, balance); console.log(formatted); // "1.5 ETH" ``` ## Error Handling The SDK provides typed errors for precise error handling. ```typescript import { SdkError, SdkErrorTypes } from "@keyban/sdk-base"; try { await account.transfer(recipient, amount); } catch (error) { if (error instanceof SdkError) { switch (error.type) { case SdkErrorTypes.InsufficientFunds: console.error("Not enough balance"); break; case SdkErrorTypes.AddressInvalid: console.error("Invalid recipient address"); break; case SdkErrorTypes.AmountInvalid: console.error("Invalid amount"); break; default: console.error("SDK error:", error.message); } } else { console.error("Unexpected error:", error); } } ``` ### Available Error Types **SdkErrorTypes:** - `AddressInvalid` - Invalid blockchain address format - `AmountInvalid` - Invalid amount (zero, negative, or exceeds limits) - `AmountRequired` - Amount is required but not provided - `AmountIrrelevant` - Amount provided when not needed - `RecipientAddressEqualsSender` - Cannot send to yourself - `EstimateGasExecution` - Gas estimation failed - `InsufficientFunds` - Insufficient balance - `InvalidNftStandard` - Unsupported NFT standard - `NftNotFound` - NFT not found - `TokenBalanceNotFound` - Token balance not found - `UnknownTransactionError` - Unknown transaction error - `UnknownIframeApiError` - Unknown API communication error **Other Error Classes:** - `CryptoError` - Cryptographic operations (encrypt, decrypt, key import) - `JwtError` - Token parsing/validation - `IFrameApiError` - IFrame communication errors ## Custom Client Share Provider Implement custom storage for MPC client shares. ```typescript import { ClientShareProvider } from "@keyban/sdk-base"; class MyClientShareProvider implements ClientShareProvider { async get(key: string): Promise<string | null> { // Retrieve from your backend const response = await fetch(`/api/shares/${key}`, { headers: { Authorization: `Bearer ${userToken}` }, }); return response.ok ? await response.text() : null; } async set(key: string, clientShare: string): Promise<void> { // Store in your backend await fetch("/api/shares", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${userToken}`, }, body: JSON.stringify({ key, clientShare }), }); } } // Use custom provider const client = new KeybanClient({ appId: "your-app-id", network: Network.PolygonAmoy, clientShareProvider: new MyClientShareProvider(), }); ``` ### Security Best Practices - Protect storage endpoints with authentication - Use per-user keys (not shared keys) - Enable audit logging for access - Never expose client shares in logs or error messages - Consider encryption at rest - Implement key rotation if possible ## Authentication & API Services The SDK provides access to additional services through `client.api`: ```typescript // Authentication await client.api.auth.signUp({ email, password }); await client.api.auth.signIn({ email, password }); await client.api.auth.sendOtp({ email }); // Account info const address = await client.api.account.getAddress(); const accountId = await client.api.account.getAccountId(); // Application info const app = await client.api.application.getApplication(); console.log("App:", app.name, app.features); // Signer operations (advanced) await client.api.signerEcdsa.dkg(); const signature = await client.api.signerEcdsa.sign(message); ``` ## Network Configuration ### Fee Units | Network | Fee Unit | Decimals | Example | |---------|----------|----------|---------| | EVM (Ethereum, Polygon) | gwei | 9 | 20 gwei = 20_000_000_000 wei | | Starknet | FRI | 18 | 1 FRI = 1_000_000_000_000_000_000 | | Stellar | stroop | 7 | 100 stroops = 0.00001 XLM | ### Native Currency | Network | Symbol | Decimals | |---------|--------|----------| | Ethereum Anvil | ETH | 18 | | Polygon Amoy | POL | 18 | | Starknet | STRK | 18 | | Stellar | XLM | 7 | ## Development ```bash # Build the package npm run build # Type check npm run typecheck # Run tests npm test # Lint npm run lint ``` ## Compatibility - **Node.js**: 18+ recommended - **Browsers**: Modern browsers with ESM support - **TypeScript**: 5.0+ for best type inference - **Bundlers**: Vite, webpack, rollup supported ## Related Packages - **[@keyban/types](https://docs.keyban.io/api/types/)** - Shared TypeScript types and Zod schemas - **[@keyban/sdk-react](https://docs.keyban.io/api/sdk-react/)** - React hooks and components - **[API Documentation](https://docs.keyban.io/api/sdk-base/)** - Full TypeDoc reference ## License See the [main repository](https://github.com/keyban-io/dap) for license information.