UNPKG

filecoin-pin

Version:

Bridge IPFS content to Filecoin Onchain Cloud using familiar tools

424 lines 16.5 kB
/** * Synapse SDK Payment Operations * * This module demonstrates comprehensive payment operations using the Synapse SDK, * providing patterns for interacting with the Filecoin Onchain Cloud payment * system (Filecoin Pay). * * Key concepts demonstrated: * - Native FIL balance checking for gas fees * - ERC20 token (USDFC) balance management * - Two-step deposit process (approve + deposit) * - Service approval configuration for storage operators * - Storage capacity calculations from pricing * * @module synapse/payments */ import { type Synapse } from '@filoz/synapse-sdk'; import type { PaymentStatus, ServiceApprovalStatus, StorageAllowances, StorageRunwaySummary } from './types.js'; export * from './constants.js'; export * from './floor-pricing.js'; export * from './top-up.js'; export * from './types.js'; /** * Compute adaptive integer scaling for a TiB value so that * Math.floor(storageTiB * scale) stays within Number.MAX_SAFE_INTEGER. * This allows us to handle numbers as small as 1/10_000_000 TiB and as large as Number.MAX_SAFE_INTEGER TiB (> 1 YiB) */ export declare function getStorageScale(storageTiB: number): number; /** * Check FIL balance for gas fees * * Example usage: * ```typescript * const synapse = await Synapse.create({ privateKey, rpcURL }) * const filStatus = await checkFILBalance(synapse) * * if (filStatus.balance === 0n) { * console.log('Account does not exist on-chain or has no FIL') * } else if (!filStatus.hasSufficientGas) { * console.log('Insufficient FIL for gas fees') * } * ``` * * @param synapse - Initialized Synapse instance * @returns Balance information and network type */ export declare function checkFILBalance(synapse: Synapse): Promise<{ balance: bigint; isCalibnet: boolean; hasSufficientGas: boolean; }>; /** * Check USDFC token balance in wallet * * Example usage: * ```typescript * const synapse = await Synapse.create({ privateKey, rpcURL }) * const walletUsdfcBalance = await checkUSDFCBalance(synapse) * * if (walletUsdfcBalance === 0n) { * console.log('No USDFC tokens found') * } else { * const formatted = ethers.formatUnits(walletUsdfcBalance, USDFC_DECIMALS) * console.log(`USDFC Balance: ${formatted}`) * } * ``` * * @param synapse - Initialized Synapse instance * @returns bigint USDFC balance in wallet (0 if account doesn't exist or has no balance) */ export declare function checkUSDFCBalance(synapse: Synapse): Promise<bigint>; /** * Get deposited USDFC balance in Payments contract * * This is different from wallet balance - it's the amount * already deposited and available for payment rails. * * @param synapse - Initialized Synapse instance * @returns Deposited USDFC balance in its smallest unit */ export declare function getDepositedBalance(synapse: Synapse): Promise<bigint>; /** * Get current payment status including all balances and approvals * * Example usage: * ```typescript * const status = await getPaymentStatus(synapse) * console.log(`Address: ${status.address}`) * console.log(`FIL Balance: ${ethers.formatEther(status.filBalance)}`) * console.log(`USDFC Balance: ${ethers.formatUnits(status.walletUsdfcBalance, 18)}`) * console.log(`Deposited: ${ethers.formatUnits(status.filecoinPayBalance, 18)}`) * ``` * * @param synapse - Initialized Synapse instance * @returns Complete payment status */ export declare function getPaymentStatus(synapse: Synapse): Promise<PaymentStatus>; export interface PaymentValidationResult { isValid: boolean; errorMessage?: string; helpMessage?: string; } export declare function validatePaymentRequirements(hasSufficientGas: boolean, walletUsdfcBalance: bigint, isCalibnet: boolean): PaymentValidationResult; /** * Deposit USDFC into the Payments contract * * This demonstrates the single-step process required for depositing ERC20 tokens: * 1. If approval is insufficient, use permit to approve and deposit in one transaction * 2. If approval is sufficient, directly call deposit * * Example usage: * ```typescript * const amountToDeposit = ethers.parseUnits('100', 18) // 100 USDFC * const { depositTx } = await depositUSDFC(synapse, amountToDeposit) * console.log(`Deposit transaction: ${depositTx}`) * ``` * * @param synapse - Initialized Synapse instance * @param amount - Amount to deposit in USDFC (with decimals) * @returns Transaction hashes for approval and deposit */ export declare function depositUSDFC(synapse: Synapse, amount: bigint): Promise<{ depositTx: string; }>; /** * Withdraw USDFC from the Payments contract back to the wallet * * Example usage: * ```typescript * const amountToWithdraw = ethers.parseUnits('10', 18) // 10 USDFC * const txHash = await withdrawUSDFC(synapse, amountToWithdraw) * console.log(`Withdraw transaction: ${txHash}`) * ``` * * @param synapse - Initialized Synapse instance * @param amount - Amount to withdraw in USDFC (with decimals) * @returns Transaction hash for the withdrawal */ export declare function withdrawUSDFC(synapse: Synapse, amount: bigint): Promise<string>; /** * Set service approvals for WarmStorage operator * * This authorizes the WarmStorage contract to create payment rails on behalf * of the user. The approval consists of three parameters: * - Rate allowance: Maximum payment rate per epoch (30 seconds) * - Lockup allowance: Maximum funds that can be locked at once * - Max lockup period: How far in advance funds can be locked (in epochs) * * Example usage: * ```typescript * // Allow up to 10 USDFC per epoch rate, 1000 USDFC total lockup * const rate = ethers.parseUnits('10', 18) * const lockup = ethers.parseUnits('1000', 18) * const txHash = await setServiceApprovals(synapse, rate, lockup) * console.log(`Approval transaction: ${txHash}`) * ``` * * @param synapse - Initialized Synapse instance * @param rateAllowance - Maximum rate per epoch in USDFC * @param lockupAllowance - Maximum lockup amount in USDFC * @returns Transaction hash */ export declare function setServiceApprovals(synapse: Synapse, rateAllowance: bigint, lockupAllowance: bigint): Promise<string>; /** * Check if WarmStorage allowances are at maximum * * This function checks whether the current allowances for WarmStorage * are already set to maximum values (effectively infinite). * * @param synapse - Initialized Synapse instance * @returns Current allowances and whether they need updating */ export declare function checkAllowances(synapse: Synapse): Promise<{ needsUpdate: boolean; currentAllowances: ServiceApprovalStatus; }>; /** * Result of setting maximum allowances for WarmStorage */ export interface SetMaxAllowancesResult { /** Transaction hash of the allowance update */ transactionHash: string; /** Updated allowance status after the transaction */ currentAllowances: ServiceApprovalStatus; } /** * Set WarmStorage allowances to maximum * * This function sets the allowances for WarmStorage to maximum values, * effectively treating it as a fully trusted service. * * @param synapse - Initialized Synapse instance * @returns Transaction hash and updated allowances */ export declare function setMaxAllowances(synapse: Synapse): Promise<SetMaxAllowancesResult>; /** * Check and automatically set WarmStorage allowances to maximum if needed * * This function treats WarmStorage as a fully trusted service and ensures * that rate and lockup allowances are always set to maximum values. * This simplifies the user experience by removing the need to understand * and configure complex allowance settings by assuming that WarmStorage * can be fully trusted to manage payments on the user's behalf. * * The function will: * 1. Check current allowances for WarmStorage * 2. If either is not at maximum, update them to MAX_UINT256 * 3. Return information about what was done * * **Session Key Authentication**: When using session key authentication, * this function will not attempt to update allowances since payment * operations require the owner wallet to sign. The function will return * `updated: false` and current allowances, which may not be at maximum. * * Example usage: * ```typescript * // Call before any operation that requires payments * const result = await checkAndSetAllowances(synapse) * if (result.updated) { * console.log(`Allowances updated: ${result.transactionHash}`) * } * ``` * * @param synapse - Initialized Synapse instance * @returns Result indicating if allowances were updated and transaction hash if applicable */ export declare function checkAndSetAllowances(synapse: Synapse): Promise<{ updated: boolean; transactionHash?: string; currentAllowances: ServiceApprovalStatus; }>; /** * Calculate storage allowances from TiB per month * * This utility converts human-friendly storage units (TiB/month) into the * epoch-based rates required by the payment system. It uses the actual * pricing from the storage service to calculate accurate allowances. * * Example usage: * ```typescript * const storageInfo = await synapse.storage.getStorageInfo() * const pricing = storageInfo.pricing.noCDN.perTiBPerEpoch * * // Calculate allowances for 10 TiB/month * const allowances = calculateStorageAllowances(10, pricing) * console.log(`Rate needed: ${ethers.formatUnits(allowances.rateAllowance, 18)} USDFC/epoch`) * ``` * * @param storageTiB - Desired storage capacity in TiB/month * @param pricePerTiBPerEpoch - Current pricing from storage service * @returns Calculated allowances for the specified capacity */ export declare function calculateStorageAllowances(storageTiB: number, pricePerTiBPerEpoch: bigint): StorageAllowances; /** * Calculate actual storage capacity from current allowances * * This is the inverse of calculateStorageAllowances - it determines how much * storage capacity the current allowances support. * * @param rateAllowance - Current rate allowance in its smallest unit * @param pricePerTiBPerEpoch - Current pricing from storage service * @returns Storage capacity in TiB that can be supported */ export declare function calculateActualCapacity(rateAllowance: bigint, pricePerTiBPerEpoch: bigint): number; /** * Calculate storage capacity from USDFC amount * * Determines how much storage can be purchased with a given USDFC amount, * accounting for the 30-day lockup period. * * @param usdfcAmount - Amount of USDFC in its smallest unit * @param pricePerTiBPerEpoch - Current pricing from storage service * @returns Storage capacity in TiB/month */ export declare function calculateStorageFromUSDFC(usdfcAmount: bigint, pricePerTiBPerEpoch: bigint): number; /** * Compute the additional deposit required to fund current usage for a duration. * * The WarmStorage service maintains ~30 days of lockup (lockupUsed) and draws future * lockups from the available deposit (deposited - lockupUsed). To keep the current * rails alive for N days, ensure available >= N days of spend at the current rateUsed. * * @param status - Current payment status (from getPaymentStatus) * @param days - Number of days to keep the current usage funded * @returns Breakdown of required top-up and related values */ export declare function computeTopUpForDuration(status: PaymentStatus, days: number): { topUp: bigint; available: bigint; rateUsed: bigint; perDay: bigint; lockupUsed: bigint; }; /** * Compute the exact adjustment (deposit or withdraw) needed to set runway to `days`. * * Positive result indicates a deposit is needed; negative indicates a withdrawal is possible. */ export declare function computeAdjustmentForExactDays(status: PaymentStatus, days: number): { delta: bigint; targetAvailable: bigint; available: bigint; rateUsed: bigint; perDay: bigint; lockupUsed: bigint; }; /** * Compute the exact adjustment (deposit or withdraw) to reach a target absolute deposit. * * Clamps to not withdraw below the currently locked amount. */ export declare function computeAdjustmentForExactDeposit(status: PaymentStatus, targetDeposit: bigint): { delta: bigint; clampedTarget: bigint; lockupUsed: bigint; }; /** * Compute adjustment needed to maintain target runway AFTER adding a new piece * * This function accounts for both: * - The new piece's lockup requirement * - The new piece's ongoing per-epoch cost (rate) * * @param status - Current payment status * @param days - Target runway in days * @param pieceSizeBytes - Size of the piece (CAR, File, etc.) file being uploaded in bytes * @param pricePerTiBPerEpoch - Current pricing from storage service * @returns Adjustment details including total delta needed */ export declare function computeAdjustmentForExactDaysWithPiece(status: PaymentStatus, days: number, pieceSizeBytes: number, pricePerTiBPerEpoch: bigint): { delta: bigint; targetDeposit: bigint; currentDeposit: bigint; newLockupUsed: bigint; newRateUsed: bigint; }; /** * Calculate storage capacity from deposit amount * * This function calculates how much storage capacity a deposit can support, * treating WarmStorage as fully trusted with max allowances, i.e. not * accounting for allowance limits. If usage limits need to be accounted for * then the capacity can be capped by either deposit or allowances. * This function accounts for the 30-day lockup requirement. * * @param depositAmount - Amount deposited in USDFC * @param pricePerTiBPerEpoch - Current pricing from storage service * @returns Storage capacity information */ export declare function calculateDepositCapacity(depositAmount: bigint, pricePerTiBPerEpoch: bigint): { tibPerMonth: number; gibPerMonth: number; monthlyPayment: bigint; requiredLockup: bigint; totalRequired: bigint; isDepositSufficient: boolean; }; /** * Calculate required allowances from piece size * * Simple wrapper that converts piece size to storage allowances. * * @param pieceSizeBytes - Size of the piece (CAR, File, etc.) file in bytes * @param pricePerTiBPerEpoch - Current pricing from storage service * @returns Required allowances for the piece */ export declare function calculateRequiredAllowances(pieceSizeBytes: number, pricePerTiBPerEpoch: bigint): StorageAllowances; export declare function calculateStorageRunway(status?: Pick<PaymentStatus, 'filecoinPayBalance' | 'currentAllowances'> | null): StorageRunwaySummary; /** * Payment capacity validation for a specific file */ export interface PaymentCapacityCheck { canUpload: boolean; storageTiB: number; required: StorageAllowances; issues: { insufficientDeposit?: bigint; insufficientRateAllowance?: bigint; insufficientLockupAllowance?: bigint; }; suggestions: string[]; } /** * Calculate piece upload deposit requirements * * @param status - Current payment status * @param pieceSizeBytes - Size of the piece (CAR, File, etc.) file in bytes * @param pricePerTiBPerEpoch - Current pricing from storage service * @returns Piece upload deposit requirements */ export declare function calculatePieceUploadRequirements(status: PaymentStatus, pieceSizeBytes: number, pricePerTiBPerEpoch: bigint): { required: StorageAllowances; totalDepositNeeded: bigint; insufficientDeposit: bigint; canUpload: boolean; }; /** * Validate payment capacity for a specific piece size * * This function checks if the deposit is sufficient for the piece upload. It * does not account for allowances since WarmStorage is assumed to be given * full trust with max allowances. * * **Note**: This function will attempt to automatically set max allowances * unless using session key authentication, in which case allowances must * be configured separately by the owner wallet. * * Example usage: * ```typescript * const fileSize = 10 * 1024 * 1024 * 1024 // 10 GiB * const capacity = await validatePaymentCapacity(synapse, fileSize) * * if (!capacity.canUpload) { * console.error('Cannot upload file with current payment setup') * capacity.suggestions.forEach(s => console.log(` - ${s}`)) * } * ``` * * @param synapse - Initialized Synapse instance * @param pieceSizeBytes - Size of the piece (CAR, File, etc.) file in bytes * @returns Capacity check result */ export declare function validatePaymentCapacity(synapse: Synapse, pieceSizeBytes: number): Promise<PaymentCapacityCheck>; //# sourceMappingURL=index.d.ts.map