# xByte > Infra for Pay-per-Byte Monetization ## API Client Reference The `xByteClient` provides methods to interact with the xByte API server for content management, pricing, and retrieval. ### Constructor #### `new xByteClient(xbyteUrl?: string)` Creates a new xByte API client instance. **Parameters:** * `xbyteUrl` (optional): The URL of the xByte API server. Defaults to `https://api.xbyte.sh` **Example:** ```typescript const client = new xByteClient(); ``` ### Health & Version #### `health()` Checks the health status of the xByte server. **Returns:** `Promise>` **Example:** ```typescript const response = await client.health(); if (response.status === "Success") { console.log(response.data); // "OK" } ``` #### `version()` Gets the version of the xByte API. **Returns:** `Promise>` **Example:** ```typescript const response = await client.version(); if (response.status === "Success") { console.log(response.data); // "1.0.0" } ``` ### Client Management #### `createClient(request: Client)` Creates a new client in the xByte system. **Parameters:** * `request`: A `Client` object with: * `name`: The name of the client * `wallet`: The wallet address associated with the client **Returns:** `Promise>` **Example:** ```typescript const response = await client.createClient({ name: "My Content Platform", wallet: "0x1234567890123456789012345678901234567890", }); if (response.status === "Success") { const clientData = response.data; console.log("Client ID:", clientData.id); } ``` #### `getClient(id: string)` Retrieves a client by its ID. **Parameters:** * `id`: The wallet address of the client **Returns:** `Promise>` **Example:** ```typescript const response = await client.getClient("0x1234567890123456789012345678901234567890"); if (response.status === "Success") { console.log("Client:", response.data); } ``` ### Storage Management #### `registerStorage(request: RegisterRequest)` Registers storage configuration for a client. This allows xByte to access the client's S3 buckets. **Parameters:** * `request`: A `RegisterRequest` object with: * `storage`: Storage configuration with S3 credentials * `client`: The wallet address of the client **Returns:** `Promise>` **Example:** ```typescript const response = await client.registerStorage({ storage: { s3: { roleArn: "arn:aws:iam::123456789012:role/xbyte-access", region: "us-east-1", }, }, client: "0x1234567890123456789012345678901234567890", }); if (response.status === "Success") { console.log("Storage registered:", response.data); } ``` #### `getAllBuckets()` Retrieves all buckets in the system. **Returns:** `Promise>` **Example:** ```typescript const response = await client.getAllBuckets(); if (response.status === "Success") { console.log("Buckets:", response.data); } ``` #### `getAllObjects(bucket: string)` Gets all objects in a specific bucket. **Parameters:** * `bucket`: The name of the bucket **Returns:** `Promise>` **Example:** ```typescript const response = await client.getAllObjects("my-content-bucket"); if (response.status === "Success") { console.log("Objects:", response.data); } ``` ### Price Management #### `setPrice(request: SetPriceRequest)` Sets the per-byte price for a content object. **Parameters:** * `request`: A `SetPriceRequest` object with: * `bucket`: The name of the bucket containing the object * `object`: The name/path of the object * `price`: The price per byte (in USDC) **Returns:** `Promise>` **Example:** ```typescript const response = await client.setPrice({ bucket: "my-content-bucket", object: "my-video.mp4", price: 0.001, }); if (response.status === "Success") { console.log("Price set successfully"); } ``` #### `getPrice(bucket: string, object: string)` Retrieves the price for a specific content object. **Parameters:** * `bucket`: The name of the bucket * `object`: The name/path of the object **Returns:** `Promise>` **Example:** ```typescript const response = await client.getPrice("my-content-bucket", "my-video.mp4"); if (response.status === "Success") { console.log("Price per byte:", response.data); } ``` ### Response Types All methods return an `ApiResponse` which can have one of three statuses: * `"Success"`: The operation completed successfully. Access data via `response.data` * `"Error"`: An error occurred. Error details are in `response.data` * `"PaymentRequired"`: Payment is required to complete the operation **Example error handling:** ```typescript const response = await client.getPrice("bucket", "object"); switch (response.status) { case "Success": console.log("Price:", response.data); break; case "Error": console.error("Error:", response.data); break; case "PaymentRequired": console.log("Payment required:", response.data); break; } ``` ## EVM Client Reference The `xByteEvmClient` provides methods to interact with xByte smart contracts on the Base Sepolia blockchain. This client uses [viem](https://viem.sh/) for blockchain interactions. ### Constructor #### `new xByteEvmClient(rpcUrl?: string)` Creates a new xByte EVM client instance. **Parameters:** * `rpcUrl` (optional): The RPC URL for the Base Sepolia chain. Defaults to `https://sepolia.base.org` **Example:** ```typescript const evmClient = new xByteEvmClient("https://sepolia.base.org"); ``` ### Factory Contract Methods #### `getOwner()` Gets the owner address of the xByteFactory contract. **Returns:** `Promise
` **Example:** ```typescript const owner = await evmClient.getOwner(); console.log("Factory owner:", owner); ``` #### `getVaultRelay()` Gets the vault relay address configured in the factory. **Returns:** `Promise
` **Example:** ```typescript const relay = await evmClient.getVaultRelay(); console.log("Vault relay:", relay); ``` #### `getVault(owner: Address)` Gets the vault address for a specific owner. **Parameters:** * `owner`: The address of the vault owner **Returns:** `Promise` **Example:** ```typescript const vaults = await evmClient.getVault("0x1234..."); console.log("Vaults:", vaults); ``` #### `getComputeVaultAddress(owner: Address)` Computes the vault address for an owner without creating it. **Parameters:** * `owner`: The address of the vault owner **Returns:** `Promise
` **Example:** ```typescript const computedAddress = await evmClient.getComputeVaultAddress("0x1234..."); console.log("Computed vault address:", computedAddress); ``` ### Function Signatures These methods return encoded function data that can be used with wallet providers or other tools. #### `signatureCreateVault()` Gets the encoded function data for creating a vault. **Returns:** `string` (hex-encoded function data) **Example:** ```typescript const signature = evmClient.signatureCreateVault(); console.log("Create vault signature:", signature); ``` #### `signatureWithdraw()` Gets the encoded function data for withdrawing native tokens from the factory. **Returns:** `string` (hex-encoded function data) **Example:** ```typescript const signature = evmClient.signatureWithdraw(); console.log("Withdraw signature:", signature); ``` #### `signatureWithdrawERC20(tokenAddress: Address)` Gets the encoded function data for withdrawing ERC20 tokens from the factory. **Parameters:** * `tokenAddress`: The address of the ERC20 token contract **Returns:** `string` (hex-encoded function data) **Example:** ```typescript const usdcAddress = "0x036CbD53842c5426634e7929541eC2318f3dCF7e"; const signature = evmClient.signatureWithdrawERC20(usdcAddress); console.log("Withdraw ERC20 signature:", signature); ``` ### Vault Balance Methods #### `getVaultBalance(vaultAddress: Address)` Gets the native token (ETH) balance of a vault. **Parameters:** * `vaultAddress`: The address of the vault **Returns:** `Promise` (balance in wei) **Example:** ```typescript const balance = await evmClient.getVaultBalance("0x5678..."); console.log("Vault balance (wei):", balance); console.log("Vault balance (ETH):", Number(balance) / 1e18); ``` #### `getVaultERC20Balance(vaultAddress: Address, tokenAddress: Address)` Gets the ERC20 token balance of a vault. **Parameters:** * `vaultAddress`: The address of the vault * `tokenAddress`: The address of the ERC20 token contract **Returns:** `Promise` (token balance) **Example:** ```typescript const usdcAddress = "0x036CbD53842c5426634e7929541eC2318f3dCF7e"; const balance = await evmClient.getVaultERC20Balance("0x5678...", usdcAddress); console.log("USDC balance:", balance); ``` ### Event Queries #### `getVaultEvents(address: Address, fromBlock?: bigint, toBlock?: bigint)` Retrieves vault events (WithdrawNative and Withdraw) for a specific vault. **Parameters:** * `address`: The vault address to query events for * `fromBlock` (optional): Starting block number. If not provided, defaults to 100,000 blocks before the latest * `toBlock` (optional): Ending block number. If not provided, defaults to the latest block **Returns:** `Promise` **Example:** ```typescript const events = await evmClient.getVaultEvents("0x5678..."); console.log("Vault events:", events); const recentEvents = await evmClient.getVaultEvents("0x5678...", 1000000n, 2000000n); console.log("Events in range:", recentEvents); ``` ### Contract Addresses The SDK includes the following contract addresses: * **xByteFactory**: `0x4957cDc66a60FfBf6E78baE23d18973a5dcC3e05` (Base Sepolia) ### Network The EVM client is configured for **Base Sepolia** testnet by default. Make sure you're connected to the correct network when using this client. ### Integration with Wallet Providers The function signatures returned by this client can be used with wallet providers like MetaMask, WalletConnect, or other Web3 libraries: ```typescript import { xByteEvmClient } from "xbyte-sdk"; const evmClient = new xByteEvmClient(); const createVaultSignature = evmClient.signatureCreateVault(); await window.ethereum.request({ method: "eth_sendTransaction", params: [ { to: "0x4957cDc66a60FfBf6E78baE23d18973a5dcC3e05", data: createVaultSignature, }, ], }); ``` ## Examples This page contains practical examples of using the xByte SDK in common scenarios. ### Complete Setup Flow This example shows the complete flow from creating a client to setting content prices: ```typescript import { xByteClient } from "xbyte-sdk"; async function setupContentPlatform() { const client = new xByteClient(); const clientResponse = await client.createClient({ name: "My Music Platform", wallet: "0x1234567890123456789012345678901234567890", }); if (clientResponse.status !== "Success") { throw new Error(`Failed to create client: ${clientResponse.data}`); } const clientId = clientResponse.data.id!; const storageResponse = await client.registerStorage({ storage: { s3: { roleArn: "arn:aws:iam::123456789012:role/xbyte-access", region: "us-east-1", }, }, client: clientId, }); if (storageResponse.status !== "Success") { throw new Error(`Failed to register storage: ${storageResponse.data}`); } console.log("Setup complete! Client ID:", clientId); return clientId; } ``` ### Setting Prices for Multiple Files ```typescript import { xByteClient } from "xbyte-sdk"; async function setPricesForFiles( client: xByteClient, bucket: string, files: Array<{ name: string; price: number }>, ) { const results = await Promise.allSettled( files.map((file) => client.setPrice({ bucket, object: file.name, price: file.price, }), ), ); results.forEach((result, index) => { if (result.status === "fulfilled" && result.value.status === "Success") { console.log(`✓ Price set for ${files[index].name}`); } else { console.error(`✗ Failed to set price for ${files[index].name}`); } }); } const client = new xByteClient(); await setPricesForFiles(client, "music-content", [ { name: "song1.mp3", price: 0.001 }, { name: "song2.mp3", price: 0.0015 }, { name: "album.zip", price: 0.002 }, ]); ``` ### Checking Vault Balance ```typescript import { xByteEvmClient } from "xbyte-sdk"; async function checkVaultEarnings(ownerAddress: string) { const evmClient = new xByteEvmClient(); const vaultAddress = await evmClient.getComputeVaultAddress(ownerAddress); const nativeBalance = await evmClient.getVaultBalance(vaultAddress); const usdcAddress = "0x036CbD53842c5426634e7929541eC2318f3dCF7e"; const usdcBalance = await evmClient.getVaultERC20Balance(vaultAddress, usdcAddress); console.log("Vault Address:", vaultAddress); console.log("Native Balance (ETH):", Number(nativeBalance) / 1e18); console.log("USDC Balance:", Number(usdcBalance) / 1e6); } ``` ### Monitoring Vault Events ```typescript import { xByteEvmClient } from "xbyte-sdk"; async function monitorVaultWithdrawals(vaultAddress: string) { const evmClient = new xByteEvmClient(); const events = await evmClient.getVaultEvents(vaultAddress); events.forEach((event) => { if (event.eventName === "WithdrawNative") { console.log("Native withdrawal:", { amount: event.args.amount, owner: event.args.owner, blockNumber: event.blockNumber, }); } else if (event.eventName === "Withdraw") { console.log("ERC20 withdrawal:", { amount: event.args.amount, token: event.args.token, owner: event.args.owner, blockNumber: event.blockNumber, }); } }); } ``` ### Error Handling Wrapper ```typescript import { xByteClient, ApiResponse } from "xbyte-sdk"; class XByteService { constructor(private client: xByteClient) {} async safeCall( operation: () => Promise>, errorMessage: string, ): Promise { const response = await operation(); if (response.status === "Success") { return response.data; } else if (response.status === "PaymentRequired") { throw new Error(`Payment required: ${response.data}`); } else { throw new Error(`${errorMessage}: ${response.data}`); } } async getPriceSafe(bucket: string, object: string): Promise { return this.safeCall(() => this.client.getPrice(bucket, object), "Failed to get price"); } async setPriceSafe(bucket: string, object: string, price: number): Promise { await this.safeCall( () => this.client.setPrice({ bucket, object, price }), "Failed to set price", ); } } const service = new XByteService(new xByteClient()); const price = await service.getPriceSafe("bucket", "object"); ``` ### React Hook Example ```typescript import { useState, useEffect } from "react"; import { xByteClient, ApiResponse } from "xbyte-sdk"; function useXBytePrice(bucket: string, object: string) { const [price, setPrice] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const client = new xByteClient(); client .getPrice(bucket, object) .then((response: ApiResponse) => { if (response.status === "Success") { setPrice(response.data); } else { setError(response.data); } }) .catch((err) => setError(err.message)) .finally(() => setLoading(false)); }, [bucket, object]); return { price, loading, error }; } function ContentPrice({ bucket, object }: { bucket: string; object: string }) { const { price, loading, error } = useXBytePrice(bucket, object); if (loading) return
Loading price...
; if (error) return
Error: {error}
; return
Price: {price} USDC per byte
; } ``` ### Batch Operations ```typescript import { xByteClient } from "xbyte-sdk"; async function batchGetPrices( client: xByteClient, bucket: string, objects: string[], ): Promise> { const priceMap = new Map(); await Promise.all( objects.map(async (object) => { const response = await client.getPrice(bucket, object); if (response.status === "Success") { priceMap.set(object, response.data); } }), ); return priceMap; } const client = new xByteClient(); const prices = await batchGetPrices(client, "music-content", [ "song1.mp3", "song2.mp3", "song3.mp3", ]); prices.forEach((price, object) => { console.log(`${object}: ${price} USDC per byte`); }); ``` ### Integration with Wallet ```typescript import { xByteEvmClient } from "xbyte-sdk"; async function createVaultWithWallet() { const evmClient = new xByteEvmClient(); const signature = evmClient.signatureCreateVault(); if (!window.ethereum) { throw new Error("MetaMask not found"); } const accounts = await window.ethereum.request({ method: "eth_requestAccounts", }); const txHash = await window.ethereum.request({ method: "eth_sendTransaction", params: [ { from: accounts[0], to: "0x4957cDc66a60FfBf6E78baE23d18973a5dcC3e05", data: signature, }, ], }); console.log("Transaction hash:", txHash); return txHash; } ``` ## Getting Started This guide will help you get started with the xByte SDK. You'll learn how to install the SDK, create clients, and make your first API calls. ### Installation Install the xByte SDK using your preferred package manager: ```bash npm install xbyte-sdk ``` ```bash pnpm add xbyte-sdk ``` ```bash yarn add xbyte-sdk ``` ### Prerequisites * Node.js 18+ or Bun * TypeScript (recommended) * An xByte API endpoint URL (or use the default) ### Basic Setup #### Import the SDK ```typescript import { xByteClient, xByteEvmClient } from "xbyte-sdk"; ``` #### Create an API Client The `xByteClient` is used to interact with the xByte API server: ```typescript const client = new xByteClient(); ``` If no URL is provided, it defaults to `https://api.xbyte.sh`: ```typescript const client = new xByteClient(); ``` #### Create an EVM Client The `xByteEvmClient` is used to interact with xByte smart contracts: ```typescript const evmClient = new xByteEvmClient("https://sepolia.base.org"); ``` If no RPC URL is provided, it defaults to `https://sepolia.base.org`. ### Your First API Call Let's start with a simple health check: ```typescript import { xByteClient } from "xbyte-sdk"; const client = new xByteClient(); const response = await client.health(); if (response.status === "Success") { console.log("Server is healthy:", response.data); } else { console.error("Error:", response.data); } ``` ### Working with Clients #### Creating a Client Before you can upload content or set prices, you need to create a client: ```typescript const clientResponse = await client.createClient({ name: "My Content Platform", wallet: "0x1234567890123456789012345678901234567890", }); if (clientResponse.status === "Success") { console.log("Client created:", clientResponse.data); const clientId = clientResponse.data.id; } ``` #### Registering Storage After creating a client, register your S3 storage to allow xByte to access your content: ```typescript const storageResponse = await client.registerStorage({ storage: { s3: { roleArn: "arn:aws:iam::123456789012:role/xbyte-access", region: "us-east-1", }, }, client: clientId, }); if (storageResponse.status === "Success") { console.log("Storage registered:", storageResponse.data); } ``` ### Setting Content Prices Once you have a bucket, you can set prices for your content: ```typescript const priceResponse = await client.setPrice({ bucket: "my-content-bucket", object: "my-video.mp4", price: 0.001, // Price per byte in USDC }); if (priceResponse.status === "Success") { console.log("Price set successfully"); } ``` ### Retrieving Prices Get the price for a specific content object: ```typescript const priceResponse = await client.getPrice("my-content-bucket", "my-video.mp4"); if (priceResponse.status === "Success") { console.log("Price:", priceResponse.data); } ``` ### Error Handling All API methods return an `ApiResponse` type. Always check the `status` field: ```typescript const response = await client.getPrice("bucket", "object"); if (response.status === "Success") { const price = response.data; } else if (response.status === "Error") { console.error("API Error:", response.data); } else if (response.status === "PaymentRequired") { console.log("Payment required:", response.data); } ``` ### Next Steps * Learn about all [API Client methods](/api-client) * Explore [EVM Client features](/evm-client) for blockchain interactions * Check out [practical examples](/examples) * Review the [types reference](/types) ## xByte SDK Infra for Pay-per-Byte Monetization TypeScript SDK for pay-per-byte content monetization through x402 payments. Enable content creators to monetize their content on a per-byte basis. Perfect for audio, video, and file streaming. ### What is xByte? xByte is a decentralized infrastructure protocol that allows content creators to monetize their content (audio, video, files, etc.) on a per-byte basis. Users pay for exactly what they consume using x402 payment authorization, enabling micro-payments for content streaming. ### Features * **Pay-per-byte monetization**: Set prices for your content and get paid for every byte consumed * **x402 payment integration**: Seamless payment authorization using the x402 standard * **EVM contract support**: Interact with xByte smart contracts on Base Sepolia * **Type-safe SDK**: Full TypeScript support with comprehensive type definitions * **Simple API**: Easy-to-use client interfaces for both API and blockchain interactions ### SDK Components The xByte SDK consists of two main clients: 1. **xByteClient**: Interact with the xByte API server for content management and retrieval 2. **xByteEvmClient**: Interact with xByte smart contracts on the blockchain ### Quick Start ```typescript import { xByteClient } from "xbyte-sdk"; const client = new xByteClient(); const health = await client.health(); console.log(health); // { status: "Success", data: "OK" } ``` ### Quick Installation ```bash npm install xbyte-sdk ``` ### What's Next? * [Get Started](/getting-started) - Set up the SDK and make your first API call * [API Client Reference](/api-client) - Learn about the xByteClient methods * [EVM Client Reference](/evm-client) - Learn about blockchain interactions * [Types Reference](/types) - Understand the TypeScript types and interfaces * [Examples](/examples) - See practical code examples ## Types Reference This page documents all TypeScript types and interfaces available in the xByte SDK. ### Core Types #### `ApiResponse` A discriminated union type representing API responses from the xByte API. ```typescript type ApiResponse = | { status: "Success"; data: T } | { status: "Error" | "PaymentRequired"; data: E }; ``` **Type Parameters:** * `T`: The type of data returned on success * `E`: The type of error data returned on failure **Status Values:** * `"Success"`: Operation completed successfully * `"Error"`: An error occurred * `"PaymentRequired"`: Payment is required to complete the operation **Example:** ```typescript const response: ApiResponse = await client.health(); if (response.status === "Success") { const data: string = response.data; } else { const error: string = response.data; } ``` ### Client Types #### `Client` Represents a client in the xByte system. ```typescript interface Client { id?: string; name: string; wallet: string; vault?: string; storage?: Storage; } ``` **Properties:** * `id` (optional): The unique identifier for the client (wallet address) * `name`: The name of the client * `wallet`: The wallet address associated with the client * `vault` (optional): The vault contract address for receiving payments * `storage` (optional): Storage configuration for the client's content **Example:** ```typescript const client: Client = { name: "My Content Platform", wallet: "0x1234567890123456789012345678901234567890", }; ``` #### `Storage` Represents storage configuration for a client. ```typescript type Storage = { s3: { roleArn: string; region: string; }; }; ``` **Properties:** * `s3.roleArn`: The ARN of the IAM role to assume for S3 access * `s3.region`: The AWS region where the S3 buckets are located **Example:** ```typescript const storage: Storage = { s3: { roleArn: "arn:aws:iam::123456789012:role/xbyte-access", region: "us-east-1", }, }; ``` ### Request Types #### `RegisterRequest` Request to register storage for a client. ```typescript interface RegisterRequest { storage: Storage; client: string; } ``` **Properties:** * `storage`: Storage configuration with S3 credentials * `client`: The wallet address of the client **Example:** ```typescript const request: RegisterRequest = { storage: { s3: { roleArn: "arn:aws:iam::123456789012:role/xbyte-access", region: "us-east-1", }, }, client: "0x1234567890123456789012345678901234567890", }; ``` #### `SetPriceRequest` Request to set the price for a content object. ```typescript interface SetPriceRequest { bucket: string; object: string; price: number; } ``` **Properties:** * `bucket`: The name of the bucket containing the object * `object`: The name/path of the object * `price`: The price per byte (in USDC) **Example:** ```typescript const request: SetPriceRequest = { bucket: "my-content-bucket", object: "my-video.mp4", price: 0.001, }; ``` #### `RangeRequest` Request for a byte range of content. ```typescript interface RangeRequest { offset: number; length: number; } ``` **Properties:** * `offset`: The starting byte offset * `length`: The number of bytes to retrieve **Example:** ```typescript const request: RangeRequest = { offset: 0, length: 1024 * 1024, }; ``` ### Payment Types #### `X402PaymentPayload` Represents an x402 payment authorization payload. ```typescript interface X402PaymentPayload { x402Version: number; scheme: string; network: string; payload: { signature: string; authorization: { from: string; to: string; value: string; validAfter: string; validBefore: string; nonce: string; }; }; } ``` **Properties:** * `x402Version`: The version of the x402 protocol * `scheme`: The payment scheme (e.g., "exact") * `network`: The blockchain network (e.g., "base-sepolia") * `payload.signature`: The cryptographic signature * `payload.authorization.from`: The payer's address * `payload.authorization.to`: The recipient's address * `payload.authorization.value`: The payment amount (as string) * `payload.authorization.validAfter`: Timestamp when payment becomes valid * `payload.authorization.validBefore`: Timestamp when payment expires * `payload.authorization.nonce`: Unique nonce for the payment **Example:** ```typescript const payment: X402PaymentPayload = { x402Version: 1, scheme: "exact", network: "base-sepolia", payload: { signature: "0x1234...", authorization: { from: "0xabcd...", to: "0x5678...", value: "1000", validAfter: "0", validBefore: "1893456000", nonce: "0xef01...", }, }, }; ``` ### Utility Types #### `Address` A type alias for Ethereum addresses (from `viem`). ```typescript import { Address } from "viem"; ``` **Example:** ```typescript const wallet: Address = "0x1234567890123456789012345678901234567890"; ``` ### Type Guards You can use TypeScript's type narrowing with the `ApiResponse` type: ```typescript function handleResponse(response: ApiResponse) { if (response.status === "Success") { return response.data; } else { throw new Error(response.data); } } ``` ### Common Patterns #### Error Handling Pattern ```typescript async function safeApiCall(apiCall: () => Promise>): Promise { const response = await apiCall(); if (response.status === "Success") { return response.data; } else { throw new Error(`API Error: ${response.data}`); } } const price = await safeApiCall(() => client.getPrice("bucket", "object")); ``` #### Type-Safe Response Handling ```typescript function isSuccess(response: ApiResponse): response is { status: "Success"; data: T } { return response.status === "Success"; } const response = await client.getPrice("bucket", "object"); if (isSuccess(response)) { console.log("Price:", response.data); } ```