UNPKG

bnksy-sdk

Version:

Complete SDK for Banksy payments - Crypto, PIX, Fiat-to-Crypto, and Payouts

567 lines (566 loc) 16 kB
// src/index.ts import { Wallet } from "ethers"; var BanksySDK = class { constructor(config) { // Crypto payout sub-module this.cryptoPayout = null; this.apiKey = config.apiKey; this.serverUrl = (config.serverUrl || "https://api.banksy.io").replace(/\/$/, ""); this.pixPayout = new PixPayoutModule(this); this.fiatCryptoPayout = new FiatCryptoPayoutModule(this); } // ============ Payment Methods ============ /** * Create a new payment * Supports: Crypto, PIX, Fiat-to-Crypto */ async createPayment(options) { const body = { successCallback: options.successCallback, failureCallback: options.failureCallback }; if (options.crypto) { body.crypto = options.crypto; if (options.fiatAmount && options.fiatCurrency) { body.fiatAmount = options.fiatAmount; body.fiatCurrency = options.fiatCurrency; } else { body.amount = options.amount; } } else if (options.currency) { body.currency = options.currency; body.amount = options.amount; } if (options.externalClientId) body.externalClientId = options.externalClientId; if (options.context) body.context = options.context; if (options.customerName) body.customerName = options.customerName; if (options.customerEmail) body.customerEmail = options.customerEmail; if (options.customerPhone) body.customerPhone = options.customerPhone; if (options.details) body.details = options.details; const response = await this.request("POST", "/sdk/payment/create", body); return { success: true, payment: response }; } /** * Get payment by ID */ async getPayment(paymentId) { return this.request("GET", `/sdk/payment/${paymentId}`); } /** * Get payment status */ async getPaymentStatus(paymentId) { return this.request("GET", `/sdk/payment/status/${paymentId}`); } /** * Get multiple payments by IDs */ async getPayments(ids) { return this.request("POST", "/sdk/payment/getPayments", { ids }); } /** * Get all payments with pagination */ async getAllPayments(options) { const params = new URLSearchParams(); if (options?.status) params.append("status", options.status); if (options?.skip !== void 0) params.append("skip", options.skip.toString()); if (options?.limit !== void 0) params.append("limit", options.limit.toString()); const query = params.toString(); return this.request("GET", `/sdk/payment/all${query ? `?${query}` : ""}`); } /** * Verify a payment (mark as verified) */ async verifyPayment(paymentId) { return this.request("PATCH", `/sdk/payment/verify/${paymentId}`); } /** * Confirm a payment manually */ async confirmPayment(paymentId, options) { return this.request("POST", "/sdk/payment/confirm", { id: paymentId, ...options }); } /** * Create a refund for a payment */ async createRefund(paymentId, options) { return this.request("POST", `/sdk/payment/refund/${paymentId}`, options || {}); } // ============ Withdraw Methods ============ /** * Create a crypto withdrawal */ async createWithdraw(options) { return this.request("POST", "/sdk/withdraw/create", options); } /** * Create a bank withdrawal */ async createBankWithdraw(options) { return this.request("POST", "/sdk/withdraw/create-bank", options); } // ============ Utility Methods ============ /** * Check API status */ async checkStatus() { return this.request("GET", "/sdk/common/status"); } /** * Get available payment providers */ async getProviders() { return this.request("GET", "/sdk/common/providers"); } /** * Get supported crypto contracts */ async getContracts() { return this.request("GET", "/sdk/common/contracts"); } /** * Get API key info */ async getKeyInfo() { return this.request("GET", "/sdk/common/getKey"); } // ============ Crypto Payout Methods ============ /** * Initialize crypto payout module * Required for processing payouts via PayoutProcessor contract */ initCryptoPayout(config) { this.cryptoPayout = new CryptoPayoutModule(this, config); return this.cryptoPayout; } // ============ Internal Methods ============ /** * Make authenticated request to Banksy server */ async request(method, path, body) { const url = `${this.serverUrl}${path}`; const headers = { "Content-Type": "application/json", "x-auth": this.apiKey }; const options = { method, headers }; if (body && method !== "GET") { options.body = JSON.stringify(body); } const response = await fetch(url, options); const json = await response.json(); if (!response.ok) { throw new Error(json.error || json.message || `Request failed: ${response.status}`); } if (json.data !== void 0) { return json.data; } return json; } /** * Get server URL (for sub-modules) */ getServerUrl() { return this.serverUrl; } /** * Get API key (for sub-modules) */ getApiKey() { return this.apiKey; } }; var CryptoPayoutModule = class { constructor(sdk, config) { this.sdk = sdk; this.wallet = new Wallet(config.privateKey); const apiKey = sdk.getApiKey(); this.network = apiKey.includes("_test_") ? "sepolia" : "mainnet"; } /** * Get client registration status */ async getClientStatus() { return this.request( "GET", `/sdk/crypto-payout/client/status?wallet=${this.wallet.address}` ); } /** * Get wallet balances */ async getBalanceInfo() { return this.request( "GET", `/sdk/crypto-payout/balance?wallet=${this.wallet.address}` ); } /** * Check if contract is paused */ async isPaused() { const response = await this.request("GET", "/sdk/crypto-payout/status"); return response.paused; } /** * Calculate payout breakdown */ async calculatePayout(amount) { return this.request( "GET", `/sdk/crypto-payout/calculate?wallet=${this.wallet.address}&amount=${amount}` ); } /** * Check if approval is needed */ async needsApproval(amount) { const response = await this.request( "GET", `/sdk/crypto-payout/check-approval?wallet=${this.wallet.address}&amount=${amount}` ); return response.needsApproval; } /** * Approve USDT spending */ async approve(amount) { const txRequest = await this.request( "POST", "/sdk/crypto-payout/approve/prepare", { wallet: this.wallet.address, amount } ); const txHash = await this.signAndBroadcast(txRequest); await this.request("POST", "/sdk/crypto-payout/approve/confirm", { wallet: this.wallet.address, txHash }); return txHash; } /** * Process a single payout */ async processPayout(recipient, amount, reference) { await this.preflight(amount); const txRequest = await this.request( "POST", "/sdk/crypto-payout/process/prepare", { wallet: this.wallet.address, recipient, amount, reference: reference || "" } ); const txHash = await this.signAndBroadcast(txRequest); return this.request( "POST", "/sdk/crypto-payout/process/confirm", { wallet: this.wallet.address, txHash, recipient, amount, reference } ); } /** * Process batch payouts */ async processPayoutsBatch(payouts) { const total = payouts.reduce((sum, p) => sum + parseFloat(p.amount), 0); await this.preflight(total.toString()); const txRequest = await this.request( "POST", "/sdk/crypto-payout/batch/prepare", { wallet: this.wallet.address, payouts: payouts.map((p) => ({ recipient: p.recipient, amount: p.amount, reference: p.reference || "" })) } ); const txHash = await this.signAndBroadcast(txRequest); return this.request( "POST", "/sdk/crypto-payout/batch/confirm", { wallet: this.wallet.address, txHash, payouts } ); } /** * Estimate gas for payout */ async estimateGas(recipient, amount) { return this.request( "POST", "/sdk/crypto-payout/estimate-gas", { wallet: this.wallet.address, recipient, amount } ); } /** * Get wallet address */ getAddress() { return this.wallet.address; } /** * Get network */ getNetwork() { return this.network; } // Private methods async request(method, path, body) { const url = `${this.sdk.getServerUrl()}${path}`; const headers = { "Content-Type": "application/json", "x-auth": this.sdk.getApiKey(), "X-Network": this.network }; const options = { method, headers }; if (body && method !== "GET") { options.body = JSON.stringify(body); } const response = await fetch(url, options); const json = await response.json(); if (!response.ok || json.success === false) { throw new Error(json.error || json.message || "Request failed"); } return json.data !== void 0 ? json.data : json; } async signAndBroadcast(txRequest) { const tx = { to: txRequest.to, data: txRequest.data, value: txRequest.value, gasLimit: txRequest.gasLimit, chainId: txRequest.chainId, nonce: txRequest.nonce, type: 2, maxFeePerGas: txRequest.maxFeePerGas, maxPriorityFeePerGas: txRequest.maxPriorityFeePerGas }; const signedTx = await this.wallet.signTransaction(tx); const result = await this.request( "POST", "/sdk/crypto-payout/broadcast", { signedTransaction: signedTx } ); return result.txHash; } async preflight(amount) { const balance = await this.getBalanceInfo(); if (parseFloat(balance.usdtBalance) < parseFloat(amount)) { throw new Error( `Insufficient USDT balance. Have: ${balance.usdtBalance}, Need: ${amount}` ); } if (parseFloat(balance.allowance) < parseFloat(amount)) { throw new Error( `Insufficient allowance. Have: ${balance.allowance}, Need: ${amount}. Call approve() first.` ); } const paused = await this.isPaused(); if (paused) { throw new Error("PayoutProcessor contract is currently paused"); } } }; var PixPayoutModule = class { constructor(sdk) { this.sdk = sdk; } /** * Create a PIX payout (send money to recipient in Brazil) */ async create(options) { return this.sdk.request("POST", "/sdk/pix-payout/create", { amount: options.amount, pixKey: options.pixKey, pixKeyType: options.pixKeyType, recipient: options.recipient, reference: options.reference }); } /** * Get payout by ID */ async get(payoutId) { return this.sdk.request("GET", `/sdk/pix-payout/${payoutId}`); } /** * Get payout status */ async getStatus(payoutId) { return this.sdk.request("GET", `/sdk/pix-payout/status/${payoutId}`); } /** * List payouts with pagination */ async list(options) { const params = new URLSearchParams(); if (options?.status) params.append("status", options.status); if (options?.skip !== void 0) params.append("skip", options.skip.toString()); if (options?.limit !== void 0) params.append("limit", options.limit.toString()); const query = params.toString(); return this.sdk.request("GET", `/sdk/pix-payout/list${query ? `?${query}` : ""}`); } /** * Get StarsPay account balance */ async getBalance() { return this.sdk.request("GET", "/sdk/pix-payout/balance"); } /** * Validate a CPF document */ async validateCPF(cpf) { return this.sdk.request("POST", "/sdk/pix-payout/validate-cpf", { cpf }); } }; var FiatCryptoPayoutModule = class { constructor(sdk) { this.sdk = sdk; const apiKey = sdk.getApiKey(); this.network = apiKey.includes("_test_") ? "sepolia" : "mainnet"; } /** * Get supported fiat currencies */ async getSupportedCurrencies() { return this.request("GET", "/sdk/fiat-crypto-payout/supported-currencies"); } /** * Get current exchange rate */ async getExchangeRate(fiatCurrency = "USD", cryptoToken = "USDT") { return this.request( "GET", `/sdk/fiat-crypto-payout/rate?fiatCurrency=${fiatCurrency}&cryptoToken=${cryptoToken}` ); } /** * Get a quote for fiat-to-crypto payout (preview before creating) */ async getQuote(options) { return this.request("POST", "/sdk/fiat-crypto-payout/quote", { wallet: options.wallet, fiatAmount: options.fiatAmount, fiatCurrency: options.fiatCurrency || "USD", cryptoToken: options.cryptoToken || "USDT" }); } /** * Create a fiat-to-crypto payout * Step 1: Creates payout record and locks in exchange rate */ async create(options) { return this.request("POST", "/sdk/fiat-crypto-payout/create", { wallet: options.wallet, recipient: options.recipient, fiatAmount: options.fiatAmount, fiatCurrency: options.fiatCurrency || "USD", cryptoToken: options.cryptoToken || "USDT", reference: options.reference, metadata: options.metadata }); } /** * Prepare payout transaction for signing * Step 2: Gets transaction data after payout is created */ async prepare(payoutId, wallet) { return this.request("POST", `/sdk/fiat-crypto-payout/${payoutId}/prepare`, { wallet }); } /** * Confirm payout after transaction is broadcasted * Step 3: Confirms the payout with transaction hash */ async confirm(payoutId, txHash) { return this.request("POST", `/sdk/fiat-crypto-payout/${payoutId}/confirm`, { txHash }); } /** * Get payout by ID */ async get(payoutId) { return this.request("GET", `/sdk/fiat-crypto-payout/${payoutId}`); } /** * List payouts with pagination */ async list(options) { const params = new URLSearchParams(); if (options?.page) params.append("page", options.page.toString()); if (options?.limit) params.append("limit", options.limit.toString()); if (options?.status) params.append("status", options.status); if (options?.fiatCurrency) params.append("fiatCurrency", options.fiatCurrency); if (options?.wallet) params.append("wallet", options.wallet); if (options?.startDate) params.append("startDate", options.startDate); if (options?.endDate) params.append("endDate", options.endDate); const query = params.toString(); return this.request("GET", `/sdk/fiat-crypto-payout/list${query ? `?${query}` : ""}`); } /** * Cancel a pending payout */ async cancel(payoutId) { return this.request("POST", `/sdk/fiat-crypto-payout/${payoutId}/cancel`); } /** * Get current network */ getNetwork() { return this.network; } // Private request method with network header async request(method, path, body) { const url = `${this.sdk.getServerUrl()}${path}`; const headers = { "Content-Type": "application/json", "x-auth": this.sdk.getApiKey(), "X-Network": this.network }; const options = { method, headers }; if (body && method !== "GET") { options.body = JSON.stringify(body); } const response = await fetch(url, options); const json = await response.json(); if (!response.ok || json.success === false) { throw new Error(json.error || json.message || "Request failed"); } return json.data !== void 0 ? json.data : json; } }; function createBanksySDK(config) { return new BanksySDK(config); } var index_default = BanksySDK; export { BanksySDK, CryptoPayoutModule, FiatCryptoPayoutModule, PixPayoutModule, createBanksySDK, index_default as default };