UNPKG

voltage-payments-component

Version:

Lightweight, framework-agnostic Bitcoin payment components for web applications using Voltage Payments

1,552 lines 144 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); function noop() { } const identity = (x) => x; function run(fn) { return fn(); } function blank_object() { return /* @__PURE__ */ Object.create(null); } function run_all(fns) { fns.forEach(run); } function is_function(thing) { return typeof thing === "function"; } function safe_not_equal(a, b) { return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function"; } let src_url_equal_anchor; function src_url_equal(element_src, url) { if (element_src === url) return true; if (!src_url_equal_anchor) { src_url_equal_anchor = document.createElement("a"); } src_url_equal_anchor.href = url; return element_src === src_url_equal_anchor.href; } function is_empty(obj) { return Object.keys(obj).length === 0; } const is_client = typeof window !== "undefined"; let now = is_client ? () => window.performance.now() : () => Date.now(); let raf = is_client ? (cb) => requestAnimationFrame(cb) : noop; const tasks = /* @__PURE__ */ new Set(); function run_tasks(now2) { tasks.forEach((task) => { if (!task.c(now2)) { tasks.delete(task); task.f(); } }); if (tasks.size !== 0) raf(run_tasks); } function loop(callback) { let task; if (tasks.size === 0) raf(run_tasks); return { promise: new Promise((fulfill) => { tasks.add(task = { c: callback, f: fulfill }); }), abort() { tasks.delete(task); } }; } function append(target, node) { target.appendChild(node); } function append_styles(target, style_sheet_id, styles) { const append_styles_to = get_root_for_style(target); if (!append_styles_to.getElementById(style_sheet_id)) { const style = element("style"); style.id = style_sheet_id; style.textContent = styles; append_stylesheet(append_styles_to, style); } } function get_root_for_style(node) { if (!node) return document; const root = node.getRootNode ? node.getRootNode() : node.ownerDocument; if (root && /** @type {ShadowRoot} */ root.host) { return ( /** @type {ShadowRoot} */ root ); } return node.ownerDocument; } function append_empty_stylesheet(node) { const style_element = element("style"); style_element.textContent = "/* empty */"; append_stylesheet(get_root_for_style(node), style_element); return style_element.sheet; } function append_stylesheet(node, style) { append( /** @type {Document} */ node.head || node, style ); return style.sheet; } function insert(target, node, anchor) { target.insertBefore(node, anchor || null); } function detach(node) { if (node.parentNode) { node.parentNode.removeChild(node); } } function element(name) { return document.createElement(name); } function svg_element(name) { return document.createElementNS("http://www.w3.org/2000/svg", name); } function text(data) { return document.createTextNode(data); } function space() { return text(" "); } function empty() { return text(""); } function listen(node, event, handler, options) { node.addEventListener(event, handler, options); return () => node.removeEventListener(event, handler, options); } function attr(node, attribute, value) { if (value == null) node.removeAttribute(attribute); else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value); } function children(element2) { return Array.from(element2.childNodes); } function set_data(text2, data) { data = "" + data; if (text2.data === data) return; text2.data = /** @type {string} */ data; } function set_style(node, key, value, important) { if (value == null) { node.style.removeProperty(key); } else { node.style.setProperty(key, value, ""); } } function toggle_class(element2, name, toggle) { element2.classList.toggle(name, !!toggle); } function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) { return new CustomEvent(type, { detail, bubbles, cancelable }); } const managed_styles = /* @__PURE__ */ new Map(); let active = 0; function hash(str) { let hash2 = 5381; let i = str.length; while (i--) hash2 = (hash2 << 5) - hash2 ^ str.charCodeAt(i); return hash2 >>> 0; } function create_style_information(doc, node) { const info = { stylesheet: append_empty_stylesheet(node), rules: {} }; managed_styles.set(doc, info); return info; } function create_rule(node, a, b, duration, delay, ease, fn, uid = 0) { const step = 16.666 / duration; let keyframes = "{\n"; for (let p = 0; p <= 1; p += step) { const t = a + (b - a) * ease(p); keyframes += p * 100 + `%{${fn(t, 1 - t)}} `; } const rule = keyframes + `100% {${fn(b, 1 - b)}} }`; const name = `__svelte_${hash(rule)}_${uid}`; const doc = get_root_for_style(node); const { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node); if (!rules[name]) { rules[name] = true; stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length); } const animation = node.style.animation || ""; node.style.animation = `${animation ? `${animation}, ` : ""}${name} ${duration}ms linear ${delay}ms 1 both`; active += 1; return name; } function delete_rule(node, name) { const previous = (node.style.animation || "").split(", "); const next = previous.filter( name ? (anim) => anim.indexOf(name) < 0 : (anim) => anim.indexOf("__svelte") === -1 // remove all Svelte animations ); const deleted = previous.length - next.length; if (deleted) { node.style.animation = next.join(", "); active -= deleted; if (!active) clear_rules(); } } function clear_rules() { raf(() => { if (active) return; managed_styles.forEach((info) => { const { ownerNode } = info.stylesheet; if (ownerNode) detach(ownerNode); }); managed_styles.clear(); }); } let current_component; function set_current_component(component) { current_component = component; } function get_current_component() { if (!current_component) throw new Error("Function called outside component initialization"); return current_component; } function onMount(fn) { get_current_component().$$.on_mount.push(fn); } function onDestroy(fn) { get_current_component().$$.on_destroy.push(fn); } function createEventDispatcher() { const component = get_current_component(); return (type, detail, { cancelable = false } = {}) => { const callbacks = component.$$.callbacks[type]; if (callbacks) { const event = custom_event( /** @type {string} */ type, detail, { cancelable } ); callbacks.slice().forEach((fn) => { fn.call(component, event); }); return !event.defaultPrevented; } return true; }; } const dirty_components = []; const binding_callbacks = []; let render_callbacks = []; const flush_callbacks = []; const resolved_promise = /* @__PURE__ */ Promise.resolve(); let update_scheduled = false; function schedule_update() { if (!update_scheduled) { update_scheduled = true; resolved_promise.then(flush); } } function add_render_callback(fn) { render_callbacks.push(fn); } const seen_callbacks = /* @__PURE__ */ new Set(); let flushidx = 0; function flush() { if (flushidx !== 0) { return; } const saved_component = current_component; do { try { while (flushidx < dirty_components.length) { const component = dirty_components[flushidx]; flushidx++; set_current_component(component); update(component.$$); } } catch (e) { dirty_components.length = 0; flushidx = 0; throw e; } set_current_component(null); dirty_components.length = 0; flushidx = 0; while (binding_callbacks.length) binding_callbacks.pop()(); for (let i = 0; i < render_callbacks.length; i += 1) { const callback = render_callbacks[i]; if (!seen_callbacks.has(callback)) { seen_callbacks.add(callback); callback(); } } render_callbacks.length = 0; } while (dirty_components.length); while (flush_callbacks.length) { flush_callbacks.pop()(); } update_scheduled = false; seen_callbacks.clear(); set_current_component(saved_component); } function update($$) { if ($$.fragment !== null) { $$.update(); run_all($$.before_update); const dirty = $$.dirty; $$.dirty = [-1]; $$.fragment && $$.fragment.p($$.ctx, dirty); $$.after_update.forEach(add_render_callback); } } function flush_render_callbacks(fns) { const filtered = []; const targets = []; render_callbacks.forEach((c) => fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c)); targets.forEach((c) => c()); render_callbacks = filtered; } let promise; function wait() { if (!promise) { promise = Promise.resolve(); promise.then(() => { promise = null; }); } return promise; } function dispatch(node, direction, kind) { node.dispatchEvent(custom_event(`${direction ? "intro" : "outro"}${kind}`)); } const outroing = /* @__PURE__ */ new Set(); let outros; function group_outros() { outros = { r: 0, c: [], p: outros // parent group }; } function check_outros() { if (!outros.r) { run_all(outros.c); } outros = outros.p; } function transition_in(block, local) { if (block && block.i) { outroing.delete(block); block.i(local); } } function transition_out(block, local, detach2, callback) { if (block && block.o) { if (outroing.has(block)) return; outroing.add(block); outros.c.push(() => { outroing.delete(block); if (callback) { if (detach2) block.d(1); callback(); } }); block.o(local); } else if (callback) { callback(); } } const null_transition = { duration: 0 }; function create_bidirectional_transition(node, fn, params, intro) { const options = { direction: "both" }; let config = fn(node, params, options); let t = intro ? 0 : 1; let running_program = null; let pending_program = null; let animation_name = null; let original_inert_value; function clear_animation() { if (animation_name) delete_rule(node, animation_name); } function init2(program, duration) { const d = ( /** @type {Program['d']} */ program.b - t ); duration *= Math.abs(d); return { a: t, b: program.b, d, duration, start: program.start, end: program.start + duration, group: program.group }; } function go(b) { const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition; const program = { start: now() + delay, b }; if (!b) { program.group = outros; outros.r += 1; } if ("inert" in node) { if (b) { if (original_inert_value !== void 0) { node.inert = original_inert_value; } } else { original_inert_value = /** @type {HTMLElement} */ node.inert; node.inert = true; } } if (running_program || pending_program) { pending_program = program; } else { if (css) { clear_animation(); animation_name = create_rule(node, t, b, duration, delay, easing, css); } if (b) tick(0, 1); running_program = init2(program, duration); add_render_callback(() => dispatch(node, b, "start")); loop((now2) => { if (pending_program && now2 > pending_program.start) { running_program = init2(pending_program, duration); pending_program = null; dispatch(node, running_program.b, "start"); if (css) { clear_animation(); animation_name = create_rule( node, t, running_program.b, running_program.duration, 0, easing, config.css ); } } if (running_program) { if (now2 >= running_program.end) { tick(t = running_program.b, 1 - t); dispatch(node, running_program.b, "end"); if (!pending_program) { if (running_program.b) { clear_animation(); } else { if (!--running_program.group.r) run_all(running_program.group.c); } } running_program = null; } else if (now2 >= running_program.start) { const p = now2 - running_program.start; t = running_program.a + running_program.d * easing(p / running_program.duration); tick(t, 1 - t); } } return !!(running_program || pending_program); }); } } return { run(b) { if (is_function(config)) { wait().then(() => { const opts = { direction: b ? "in" : "out" }; config = config(opts); go(b); }); } else { go(b); } }, end() { clear_animation(); running_program = pending_program = null; } }; } function create_component(block) { block && block.c(); } function mount_component(component, target, anchor) { const { fragment, after_update } = component.$$; fragment && fragment.m(target, anchor); add_render_callback(() => { const new_on_destroy = component.$$.on_mount.map(run).filter(is_function); if (component.$$.on_destroy) { component.$$.on_destroy.push(...new_on_destroy); } else { run_all(new_on_destroy); } component.$$.on_mount = []; }); after_update.forEach(add_render_callback); } function destroy_component(component, detaching) { const $$ = component.$$; if ($$.fragment !== null) { flush_render_callbacks($$.after_update); run_all($$.on_destroy); $$.fragment && $$.fragment.d(detaching); $$.on_destroy = $$.fragment = null; $$.ctx = []; } } function make_dirty(component, i) { if (component.$$.dirty[0] === -1) { dirty_components.push(component); schedule_update(); component.$$.dirty.fill(0); } component.$$.dirty[i / 31 | 0] |= 1 << i % 31; } function init(component, options, instance2, create_fragment2, not_equal, props, append_styles2 = null, dirty = [-1]) { const parent_component = current_component; set_current_component(component); const $$ = component.$$ = { fragment: null, ctx: [], // state props, update: noop, not_equal, bound: blank_object(), // lifecycle on_mount: [], on_destroy: [], on_disconnect: [], before_update: [], after_update: [], context: new Map(options.context || (parent_component ? parent_component.$$.context : [])), // everything else callbacks: blank_object(), dirty, skip_bound: false, root: options.target || parent_component.$$.root }; append_styles2 && append_styles2($$.root); let ready = false; $$.ctx = instance2 ? instance2(component, options.props || {}, (i, ret, ...rest) => { const value = rest.length ? rest[0] : ret; if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value); if (ready) make_dirty(component, i); } return ret; }) : []; $$.update(); ready = true; run_all($$.before_update); $$.fragment = create_fragment2 ? create_fragment2($$.ctx) : false; if (options.target) { if (options.hydrate) { const nodes = children(options.target); $$.fragment && $$.fragment.l(nodes); nodes.forEach(detach); } else { $$.fragment && $$.fragment.c(); } if (options.intro) transition_in(component.$$.fragment); mount_component(component, options.target, options.anchor); flush(); } set_current_component(parent_component); } class SvelteComponent { constructor() { /** * ### PRIVATE API * * Do not use, may change at any time * * @type {any} */ __publicField(this, "$$"); /** * ### PRIVATE API * * Do not use, may change at any time * * @type {any} */ __publicField(this, "$$set"); } /** @returns {void} */ $destroy() { destroy_component(this, 1); this.$destroy = noop; } /** * @template {Extract<keyof Events, string>} K * @param {K} type * @param {((e: Events[K]) => void) | null | undefined} callback * @returns {() => void} */ $on(type, callback) { if (!is_function(callback)) { return noop; } const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []); callbacks.push(callback); return () => { const index = callbacks.indexOf(callback); if (index !== -1) callbacks.splice(index, 1); }; } /** * @param {Partial<Props>} props * @returns {void} */ $set(props) { if (this.$$set && !is_empty(props)) { this.$$.skip_bound = true; this.$$set(props); this.$$.skip_bound = false; } } } const PUBLIC_VERSION = "4"; if (typeof window !== "undefined") (window.__svelte || (window.__svelte = { v: /* @__PURE__ */ new Set() })).v.add(PUBLIC_VERSION); class VoltageApiError extends Error { constructor(message, status, code, details) { super(message); this.name = "VoltageApiError"; this.status = status; this.code = code; this.details = details; } } class HttpClient { constructor(config) { this.baseUrl = config.baseUrl || "https://voltageapi.com/v1"; this.apiKey = config.apiKey; this.bearerToken = config.bearerToken; this.timeout = config.timeout || 3e4; if (this.baseUrl.endsWith("/")) { this.baseUrl = this.baseUrl.slice(0, -1); } if (typeof fetch === "undefined") { throw new Error("Fetch is not available. Please use Node.js 18+ or provide a fetch polyfill."); } } getAuthHeaders() { const headers = {}; if (this.bearerToken) { headers["Authorization"] = `Bearer ${this.bearerToken}`; } else if (this.apiKey) { headers["X-Api-Key"] = this.apiKey; } return headers; } async withTimeout(promise2, timeoutMs) { let timeoutId; const timeoutPromise = new Promise((_, reject) => { timeoutId = setTimeout(() => reject(new VoltageApiError("Request timeout", 408)), timeoutMs); }); try { const result = await Promise.race([promise2, timeoutPromise]); if (timeoutId) clearTimeout(timeoutId); return result; } catch (error) { if (timeoutId) clearTimeout(timeoutId); throw error; } } async request(endpoint, options = {}) { const { method = "GET", body, headers = {}, timeout = this.timeout } = options; const url = `${this.baseUrl}${endpoint}`; const authHeaders = this.getAuthHeaders(); const requestHeaders = __spreadValues(__spreadValues({ "Content-Type": "application/json" }, authHeaders), headers); const config = { method, headers: requestHeaders }; if (body && method !== "GET") { config.body = JSON.stringify(body); } try { const response = await this.withTimeout(fetch(url, config), timeout); const responseText = await response.text(); let data; try { data = responseText ? JSON.parse(responseText) : null; } catch (parseError) { throw new VoltageApiError("Failed to parse response as JSON", response.status, "PARSE_ERROR", parseError); } if (!response.ok) { const errorMessage = typeof data === "object" && data !== null && "message" in data ? data.message : `HTTP ${response.status}: ${response.statusText}`; throw new VoltageApiError(errorMessage, response.status, "HTTP_ERROR", data); } return { data, status: response.status, statusText: response.statusText }; } catch (error) { if (error instanceof VoltageApiError) { throw error; } throw new VoltageApiError(error instanceof Error ? error.message : "Unknown error occurred", void 0, "NETWORK_ERROR", error); } } async get(endpoint, headers) { return this.request(endpoint, { method: "GET", headers }); } async post(endpoint, body, headers) { return this.request(endpoint, { method: "POST", body, headers }); } async put(endpoint, body, headers) { return this.request(endpoint, { method: "PUT", body, headers }); } async patch(endpoint, body, headers) { return this.request(endpoint, { method: "PATCH", body, headers }); } async delete(endpoint, headers) { return this.request(endpoint, { method: "DELETE", headers }); } } const DEFAULT_POLLING_CONFIG = { maxAttempts: 30, intervalMs: 1e3, timeoutMs: 3e4 }; class VoltageClient { constructor(config) { if (!config.apiKey && !config.bearerToken) { throw new Error("Either apiKey or bearerToken must be provided"); } this.httpClient = new HttpClient(config); } /** * Get all wallets in an organization * @param params - Parameters containing organization_id * @returns Promise resolving to an array of wallets */ async getWallets(params) { const { organization_id } = params; if (!organization_id) { throw new Error("organization_id is required"); } const response = await this.httpClient.get(`/organizations/${organization_id}/wallets`); return response.data; } /** * Get a specific wallet * @param params - Parameters containing organization_id and wallet_id * @returns Promise resolving to a wallet */ async getWallet(params) { const { organization_id, wallet_id } = params; if (!organization_id || !wallet_id) { throw new Error("organization_id and wallet_id are required"); } const response = await this.httpClient.get(`/organizations/${organization_id}/wallets/${wallet_id}`); return response.data; } /** * Create a new wallet * @param params - Parameters containing organization_id and wallet data * @returns Promise resolving when wallet creation is initiated */ async createWallet(params) { const { organization_id, wallet } = params; if (!organization_id) { throw new Error("organization_id is required"); } if (!wallet) { throw new Error("wallet data is required"); } await this.httpClient.post(`/organizations/${organization_id}/wallets`, wallet); } /** * Delete a wallet * @param params - Parameters containing organization_id and wallet_id * @returns Promise resolving when wallet deletion is complete */ async deleteWallet(params) { const { organization_id, wallet_id } = params; if (!organization_id || !wallet_id) { throw new Error("organization_id and wallet_id are required"); } await this.httpClient.delete(`/organizations/${organization_id}/wallets/${wallet_id}`); } /** * Create a new payment request (invoice) and wait for it to be ready * This method abstracts the polling logic to wait for the payment to be generated * @param params - Parameters containing organization_id, environment_id, and payment data * @param pollingConfig - Optional polling configuration * @returns Promise resolving to the ready payment with payment_request or address */ async createPaymentRequest(params, pollingConfig) { const { organization_id, environment_id, payment } = params; if (!organization_id || !environment_id) { throw new Error("organization_id and environment_id are required"); } if (!payment) { throw new Error("payment data is required"); } const paymentWithId = __spreadProps(__spreadValues({}, payment), { id: payment.id || crypto.randomUUID() }); const config = __spreadValues(__spreadValues({}, DEFAULT_POLLING_CONFIG), pollingConfig); await this.httpClient.post(`/organizations/${organization_id}/environments/${environment_id}/payments`, paymentWithId); return this.pollForPayment({ organization_id, environment_id, payment_id: paymentWithId.id }, config); } /** * Get a specific payment * @param params - Parameters containing organization_id, environment_id, and payment_id * @returns Promise resolving to a payment */ async getPayment(params) { const { organization_id, environment_id, payment_id } = params; if (!organization_id || !environment_id || !payment_id) { throw new Error("organization_id, environment_id, and payment_id are required"); } const response = await this.httpClient.get(`/organizations/${organization_id}/environments/${environment_id}/payments/${payment_id}`); return response.data; } /** * Get all payments for an organization with optional filtering * @param params - Parameters containing organization_id, environment_id, and optional filters * @returns Promise resolving to paginated payments */ async getPayments(params) { const _a = params, { organization_id, environment_id } = _a, filters = __objRest(_a, ["organization_id", "environment_id"]); if (!organization_id || !environment_id) { throw new Error("organization_id and environment_id are required"); } const queryParams = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value !== void 0 && value !== null) { if (Array.isArray(value)) { value.forEach((item) => queryParams.append(key, item.toString())); } else { queryParams.append(key, value.toString()); } } }); const queryString = queryParams.toString(); const url = `/organizations/${organization_id}/environments/${environment_id}/payments${queryString ? `?${queryString}` : ""}`; const response = await this.httpClient.get(url); return response.data; } /** * Poll for a payment to be ready (status not 'generating') * @param params - Parameters for getting the payment * @param config - Polling configuration * @returns Promise resolving to the ready payment */ async pollForPayment(params, config) { const startTime = Date.now(); let attempts = 0; while (attempts < config.maxAttempts) { if (Date.now() - startTime > config.timeoutMs) { throw new Error(`Payment polling timed out after ${config.timeoutMs}ms`); } try { const payment = await this.getPayment(params); if (payment.direction !== "receive") { throw new Error("Expected receive payment but got send payment"); } const receivePayment = payment; if (receivePayment.status !== "generating") { if (receivePayment.status === "failed") { let errorMessage = "Payment generation failed"; if (receivePayment.error) { if (receivePayment.error.type === "receive_failed") { errorMessage = `Payment generation failed: ${receivePayment.error.detail}`; } else if (receivePayment.error.type === "expired") { errorMessage = "Payment generation failed: Payment expired"; } } throw new Error(errorMessage); } return receivePayment; } await this.sleep(config.intervalMs); attempts++; } catch (error) { if (error instanceof Error && error.message.includes("timed out")) { throw error; } if (error instanceof Error && error.message.includes("Payment generation failed")) { throw error; } await this.sleep(config.intervalMs); attempts++; } } throw new Error(`Payment polling failed after ${config.maxAttempts} attempts`); } /** * Sleep for the specified number of milliseconds * @param ms - Milliseconds to sleep */ sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } /** * Send a payment (Lightning, On-chain, or BIP21) * This method creates a send payment and waits for it to complete or fail * @param params - Parameters containing organization_id, environment_id, and payment data * @param pollingConfig - Optional polling configuration * @returns Promise resolving to the completed payment */ async sendPayment(params, pollingConfig) { const { organization_id, environment_id, payment } = params; if (!organization_id || !environment_id) { throw new Error("organization_id and environment_id are required"); } if (!payment) { throw new Error("payment data is required"); } const paymentWithId = __spreadProps(__spreadValues({}, payment), { id: payment.id || crypto.randomUUID() }); const config = __spreadValues(__spreadValues({}, DEFAULT_POLLING_CONFIG), pollingConfig); await this.httpClient.post(`/organizations/${organization_id}/environments/${environment_id}/payments`, paymentWithId); return this.pollForSendPayment({ organization_id, environment_id, payment_id: paymentWithId.id }, config); } /** * Poll for a send payment to complete (status not 'sending') * @param params - Parameters for getting the payment * @param config - Polling configuration * @returns Promise resolving to the completed payment */ async pollForSendPayment(params, config) { const startTime = Date.now(); let attempts = 0; while (attempts < config.maxAttempts) { if (Date.now() - startTime > config.timeoutMs) { throw new Error(`Send payment polling timed out after ${config.timeoutMs}ms`); } try { const payment = await this.getPayment(params); if (payment.direction !== "send") { throw new Error("Expected send payment but got receive payment"); } const sendPayment = payment; if (sendPayment.status !== "sending") { if (sendPayment.status === "failed") { let errorMessage = "Send payment failed"; if (sendPayment.error) { errorMessage = `Send payment failed: ${sendPayment.error.detail}`; } throw new Error(errorMessage); } return sendPayment; } await this.sleep(config.intervalMs); attempts++; } catch (error) { if (error instanceof Error && error.message.includes("timed out")) { throw error; } if (error instanceof Error && error.message.includes("Send payment failed")) { throw error; } await this.sleep(config.intervalMs); attempts++; } } throw new Error(`Send payment polling failed after ${config.maxAttempts} attempts`); } /** * Get a wallet's transaction history (ledger) * @param params - Parameters containing organization_id, wallet_id, and optional filters * @returns Promise resolving to paginated ledger events */ async getWalletLedger(params) { const _a = params, { organization_id, wallet_id } = _a, filters = __objRest(_a, ["organization_id", "wallet_id"]); if (!organization_id || !wallet_id) { throw new Error("organization_id and wallet_id are required"); } const queryParams = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value !== void 0 && value !== null) { queryParams.append(key, value.toString()); } }); const queryString = queryParams.toString(); const url = `/organizations/${organization_id}/wallets/${wallet_id}/ledger${queryString ? `?${queryString}` : ""}`; const response = await this.httpClient.get(url); return response.data; } /** * Get the history of a payment * @param params - Parameters containing organization_id, environment_id, and payment_id * @returns Promise resolving to payment history events */ async getPaymentHistory(params) { const { organization_id, environment_id, payment_id } = params; if (!organization_id || !environment_id || !payment_id) { throw new Error("organization_id, environment_id, and payment_id are required"); } const response = await this.httpClient.get(`/organizations/${organization_id}/environments/${environment_id}/payments/${payment_id}/history`); return response.data; } /** * Get a line of credit summary * @param params - Parameters containing organization_id and line_id * @returns Promise resolving to line of credit summary */ async getLineOfCredit(params) { const { organization_id, line_id } = params; if (!organization_id || !line_id) { throw new Error("organization_id and line_id are required"); } const response = await this.httpClient.get(`/organizations/${organization_id}/lines_of_credit/${line_id}/summary`); return response.data; } /** * Get all lines of credit summaries for an organization * @param params - Parameters containing organization_id * @returns Promise resolving to an array of line of credit summaries */ async getLinesOfCredit(params) { const { organization_id } = params; if (!organization_id) { throw new Error("organization_id is required"); } const response = await this.httpClient.get(`/organizations/${organization_id}/lines_of_credit/summaries`); return response.data; } /** * Get all webhooks for an organization with optional filtering * @param params - Parameters containing organization_id and optional filters * @returns Promise resolving to an array of webhooks */ async getWebhooks(params) { const _a = params, { organization_id } = _a, filters = __objRest(_a, ["organization_id"]); if (!organization_id) { throw new Error("organization_id is required"); } const queryParams = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value !== void 0 && value !== null) { if (Array.isArray(value)) { value.forEach((item) => queryParams.append(key, item.toString())); } else { queryParams.append(key, value.toString()); } } }); const queryString = queryParams.toString(); const url = `/organizations/${organization_id}/webhooks${queryString ? `?${queryString}` : ""}`; const response = await this.httpClient.get(url); return response.data; } /** * Get a specific webhook * @param params - Parameters containing organization_id, environment_id, and webhook_id * @returns Promise resolving to a webhook */ async getWebhook(params) { const { organization_id, environment_id, webhook_id } = params; if (!organization_id || !environment_id || !webhook_id) { throw new Error("organization_id, environment_id, and webhook_id are required"); } const response = await this.httpClient.get(`/organizations/${organization_id}/environments/${environment_id}/webhooks/${webhook_id}`); return response.data; } /** * Create a new webhook * @param params - Parameters containing organization_id, environment_id, and webhook data * @returns Promise resolving to webhook secret information */ async createWebhook(params) { const { organization_id, environment_id, webhook } = params; if (!organization_id || !environment_id) { throw new Error("organization_id and environment_id are required"); } if (!webhook) { throw new Error("webhook data is required"); } const webhookWithId = __spreadProps(__spreadValues({}, webhook), { id: webhook.id || crypto.randomUUID() }); const response = await this.httpClient.post(`/organizations/${organization_id}/environments/${environment_id}/webhooks`, webhookWithId); return response.data; } /** * Update a webhook * @param params - Parameters containing organization_id, environment_id, webhook_id, and webhook data * @returns Promise resolving when webhook update is complete */ async updateWebhook(params) { const { organization_id, environment_id, webhook_id, webhook } = params; if (!organization_id || !environment_id || !webhook_id) { throw new Error("organization_id, environment_id, and webhook_id are required"); } if (!webhook) { throw new Error("webhook data is required"); } await this.httpClient.patch(`/organizations/${organization_id}/environments/${environment_id}/webhooks/${webhook_id}`, webhook); } /** * Delete a webhook * @param params - Parameters containing organization_id, environment_id, and webhook_id * @returns Promise resolving when webhook deletion is complete */ async deleteWebhook(params) { const { organization_id, environment_id, webhook_id } = params; if (!organization_id || !environment_id || !webhook_id) { throw new Error("organization_id, environment_id, and webhook_id are required"); } await this.httpClient.delete(`/organizations/${organization_id}/environments/${environment_id}/webhooks/${webhook_id}`); } /** * Start a webhook * @param params - Parameters containing organization_id, environment_id, and webhook_id * @returns Promise resolving when webhook start request is complete */ async startWebhook(params) { const { organization_id, environment_id, webhook_id } = params; if (!organization_id || !environment_id || !webhook_id) { throw new Error("organization_id, environment_id, and webhook_id are required"); } await this.httpClient.post(`/organizations/${organization_id}/environments/${environment_id}/webhooks/${webhook_id}/start`); } /** * Stop a webhook * @param params - Parameters containing organization_id, environment_id, and webhook_id * @returns Promise resolving when webhook stop request is complete */ async stopWebhook(params) { const { organization_id, environment_id, webhook_id } = params; if (!organization_id || !environment_id || !webhook_id) { throw new Error("organization_id, environment_id, and webhook_id are required"); } await this.httpClient.post(`/organizations/${organization_id}/environments/${environment_id}/webhooks/${webhook_id}/stop`); } /** * Generate a new key for a webhook * @param params - Parameters containing organization_id, environment_id, and webhook_id * @returns Promise resolving to new webhook secret information */ async generateWebhookKey(params) { const { organization_id, environment_id, webhook_id } = params; if (!organization_id || !environment_id || !webhook_id) { throw new Error("organization_id, environment_id, and webhook_id are required"); } const response = await this.httpClient.post(`/organizations/${organization_id}/environments/${environment_id}/webhooks/${webhook_id}/keys`); return response.data; } /** * Get low-level HTTP client for advanced usage * @returns HttpClient instance */ getHttpClient() { return this.httpClient; } } var browser = {}; var canPromise$1 = function() { return typeof Promise === "function" && Promise.prototype && Promise.prototype.then; }; var qrcode = {}; var utils$1 = {}; let toSJISFunction; const CODEWORDS_COUNT = [ 0, // Not used 26, 44, 70, 100, 134, 172, 196, 242, 292, 346, 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085, 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185, 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706 ]; utils$1.getSymbolSize = function getSymbolSize(version2) { if (!version2) throw new Error('"version" cannot be null or undefined'); if (version2 < 1 || version2 > 40) throw new Error('"version" should be in range from 1 to 40'); return version2 * 4 + 17; }; utils$1.getSymbolTotalCodewords = function getSymbolTotalCodewords(version2) { return CODEWORDS_COUNT[version2]; }; utils$1.getBCHDigit = function(data) { let digit = 0; while (data !== 0) { digit++; data >>>= 1; } return digit; }; utils$1.setToSJISFunction = function setToSJISFunction(f) { if (typeof f !== "function") { throw new Error('"toSJISFunc" is not a valid function.'); } toSJISFunction = f; }; utils$1.isKanjiModeEnabled = function() { return typeof toSJISFunction !== "undefined"; }; utils$1.toSJIS = function toSJIS(kanji2) { return toSJISFunction(kanji2); }; var errorCorrectionLevel = {}; (function(exports) { exports.L = { bit: 1 }; exports.M = { bit: 0 }; exports.Q = { bit: 3 }; exports.H = { bit: 2 }; function fromString(string) { if (typeof string !== "string") { throw new Error("Param is not a string"); } const lcStr = string.toLowerCase(); switch (lcStr) { case "l": case "low": return exports.L; case "m": case "medium": return exports.M; case "q": case "quartile": return exports.Q; case "h": case "high": return exports.H; default: throw new Error("Unknown EC Level: " + string); } } exports.isValid = function isValid2(level) { return level && typeof level.bit !== "undefined" && level.bit >= 0 && level.bit < 4; }; exports.from = function from(value, defaultValue) { if (exports.isValid(value)) { return value; } try { return fromString(value); } catch (e) { return defaultValue; } }; })(errorCorrectionLevel); function BitBuffer$1() { this.buffer = []; this.length = 0; } BitBuffer$1.prototype = { get: function(index) { const bufIndex = Math.floor(index / 8); return (this.buffer[bufIndex] >>> 7 - index % 8 & 1) === 1; }, put: function(num, length) { for (let i = 0; i < length; i++) { this.putBit((num >>> length - i - 1 & 1) === 1); } }, getLengthInBits: function() { return this.length; }, putBit: function(bit) { const bufIndex = Math.floor(this.length / 8); if (this.buffer.length <= bufIndex) { this.buffer.push(0); } if (bit) { this.buffer[bufIndex] |= 128 >>> this.length % 8; } this.length++; } }; var bitBuffer = BitBuffer$1; function BitMatrix$1(size) { if (!size || size < 1) { throw new Error("BitMatrix size must be defined and greater than 0"); } this.size = size; this.data = new Uint8Array(size * size); this.reservedBit = new Uint8Array(size * size); } BitMatrix$1.prototype.set = function(row, col, value, reserved) { const index = row * this.size + col; this.data[index] = value; if (reserved) this.reservedBit[index] = true; }; BitMatrix$1.prototype.get = function(row, col) { return this.data[row * this.size + col]; }; BitMatrix$1.prototype.xor = function(row, col, value) { this.data[row * this.size + col] ^= value; }; BitMatrix$1.prototype.isReserved = function(row, col) { return this.reservedBit[row * this.size + col]; }; var bitMatrix = BitMatrix$1; var alignmentPattern = {}; (function(exports) { const getSymbolSize3 = utils$1.getSymbolSize; exports.getRowColCoords = function getRowColCoords(version2) { if (version2 === 1) return []; const posCount = Math.floor(version2 / 7) + 2; const size = getSymbolSize3(version2); const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2; const positions = [size - 7]; for (let i = 1; i < posCount - 1; i++) { positions[i] = positions[i - 1] - intervals; } positions.push(6); return positions.reverse(); }; exports.getPositions = function getPositions2(version2) { const coords = []; const pos = exports.getRowColCoords(version2); const posLength = pos.length; for (let i = 0; i < posLength; i++) { for (let j = 0; j < posLength; j++) { if (i === 0 && j === 0 || // top-left i === 0 && j === posLength - 1 || // bottom-left i === posLength - 1 && j === 0) { continue; } coords.push([pos[i], pos[j]]); } } return coords; }; })(alignmentPattern); var finderPattern = {}; const getSymbolSize2 = utils$1.getSymbolSize; const FINDER_PATTERN_SIZE = 7; finderPattern.getPositions = function getPositions(version2) { const size = getSymbolSize2(version2); return [ // top-left [0, 0], // top-right [size - FINDER_PATTERN_SIZE, 0], // bottom-left [0, size - FINDER_PATTERN_SIZE] ]; }; var maskPattern = {}; (function(exports) { exports.Patterns = { PATTERN000: 0, PATTERN001: 1, PATTERN010: 2, PATTERN011: 3, PATTERN100: 4, PATTERN101: 5, PATTERN110: 6, PATTERN111: 7 }; const PenaltyScores = { N1: 3, N2: 3, N3: 40, N4: 10 }; exports.isValid = function isValid2(mask) { return mask != null && mask !== "" && !isNaN(mask) && mask >= 0 && mask <= 7; }; exports.from = function from(value) { return exports.isValid(value) ? parseInt(value, 10) : void 0; }; exports.getPenaltyN1 = function getPenaltyN1(data) { const size = data.size; let points = 0; let sameCountCol = 0; let sameCountRow = 0; let lastCol = null; let lastRow = null; for (let row = 0; row < size; row++) { sameCountCol = sameCountRow = 0; lastCol = lastRow = null; for (let col = 0; col < size; col++) { let module = data.get(row, col); if (module === lastCol) { sameCountCol++; } else { if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5); lastCol = module; sameCountCol = 1; } module = data.get(col, row); if (module === lastRow) { sameCountRow++; } else { if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5); lastRow = module; sameCountRow = 1; } } if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5); if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5); } return points; }; exports.getPenaltyN2 = function getPenaltyN2(data) { const size = data.size; let points = 0; for (let row = 0; row < size - 1; row++) { for (let col = 0; col < size - 1; col++) { const last = data.get(row, col) + data.get(row, col + 1) + data.get(row + 1, col) + data.get(row + 1, col + 1); if (last === 4 || last === 0) points++; } } return points * PenaltyScores.N2; }; exports.getPenaltyN3 = function getPenaltyN3(data) { const size = data.size; let points = 0; let bitsCol = 0; let bitsRow = 0; for (let row = 0; row < size; row++) { bitsCol = bitsRow = 0; for (let col = 0; col < size; col++) { bitsCol = bitsCol << 1 & 2047 | data.get(row, col); if (col >= 10 && (bitsCol === 1488 || bitsCol === 93)) points++; bitsRow = bitsRow << 1 & 2047 | data.get(col, row); if (col >= 10 && (bitsRow === 1488 || bitsRow === 93)) points++; } } return points * PenaltyScores.N3; }; exports.getPenaltyN4 = function getPenaltyN4(data) { let darkCount = 0; const modulesCount = data.data.length; for (let i = 0; i < modulesCount; i++) darkCount += data.data[i]; const k = Math.abs(Math.ceil(darkCount * 100 / modulesCount / 5) - 10); return k * PenaltyScores.N4; }; function getMaskAt(maskPattern2, i, j) { switch (maskPattern2) { case exports.Patterns.PATTERN000: return (i + j) % 2 === 0; case exports.Patterns.PATTERN001: return i % 2 === 0; case exports.Patterns.PATTERN010: return j % 3 === 0; case exports.Patterns.PATTERN011: return (i + j) % 3 === 0; case exports.Patterns.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0; case exports.Patterns.PATTERN101: return i * j % 2 + i * j % 3 === 0; case exports.Patterns.PATTERN110: return (i * j % 2 + i * j % 3) % 2 === 0; case exports.Patterns.PATTERN111: return (i * j % 3 + (i + j) % 2) % 2 === 0; default: throw new Error("bad maskPattern:" + maskPattern2); } } exports.applyMask = function applyMask(pattern, data) { const size = data.size; for (let col = 0; col < size; col++) { for (let row = 0; row < size; row++) { if (data.isReserved(row, col)) continue; data.xor(row, col, getMaskAt(pattern, row, col)); } } }; exports.getBestMask = function getBestMask(data, setupFormatFunc) { const numPatterns = Object.keys(exports.Patterns).length; let bestPattern = 0; let lowerPenalty = Infinity; for (let p = 0; p < numPatterns; p++) { setupFormatFunc(p); exports.applyMask(p, data); const penalty = exports.getPenaltyN1(data) + exports.getPenaltyN2(data) + e