neutron-sdk 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -181,24 +181,6 @@ await neutron.webhooks.update(webhook.id, { callback: "https://myapp.com/v2/webh
181
181
  await neutron.webhooks.delete(webhook.id);
182
182
  ```
183
183
 
184
- ### Lightning Utilities
185
-
186
- ```typescript
187
- // Decode an invoice before paying
188
- const decoded = await neutron.lightning.decodeInvoice("lnbc100u1p...");
189
- console.log(decoded.amount, decoded.expiry);
190
-
191
- // Verify a Lightning Address exists
192
- const info = await neutron.lightning.resolveAddress("alice@getalby.com");
193
- console.log(info.minSendable, info.maxSendable);
194
-
195
- // Resolve an LNURL
196
- const lnurl = await neutron.lightning.resolveLnurl("lnurl1dp68gurn...");
197
- console.log(lnurl.tag); // "payRequest" or "withdrawRequest"
198
- ```
199
-
200
- ---
201
-
202
184
  ## Verify Webhook Signatures
203
185
 
204
186
  One-liner verification — no client instance needed:
@@ -300,7 +282,7 @@ try {
300
282
  const neutron = new Neutron({
301
283
  apiKey: "your-api-key", // Required
302
284
  apiSecret: "your-api-secret", // Required
303
- baseUrl: "https://enapi.npay.dev", // Sandbox (default: enapi.npay.live)
285
+ baseUrl: "https://api.neutron.me", // Custom API URL (default: api.neutron.me)
304
286
  timeout: 15000, // Request timeout in ms (default: 30000)
305
287
  maxRetries: 3, // Retry attempts for 5xx/429 (default: 2)
306
288
  debug: true, // Log requests to stderr
package/dist/index.cjs CHANGED
@@ -114,7 +114,7 @@ var NeutronValidationError = class extends NeutronError {
114
114
  };
115
115
 
116
116
  // src/client.ts
117
- var DEFAULT_BASE_URL = "https://enapi.npay.live";
117
+ var DEFAULT_BASE_URL = "https://api.neutron.me";
118
118
  var DEFAULT_TIMEOUT = 3e4;
119
119
  var DEFAULT_MAX_RETRIES = 2;
120
120
  var TOKEN_REFRESH_BUFFER_MS = 6e4;
@@ -542,34 +542,6 @@ var LightningResource = class {
542
542
  }
543
543
  });
544
544
  }
545
- /**
546
- * Decode a BOLT11 invoice to inspect it before paying.
547
- * Returns amount, expiry, destination node, description, and payment status.
548
- */
549
- async decodeInvoice(invoice) {
550
- return this.client.get(
551
- `/api/v2/lightning/invoice?invoice=${encodeURIComponent(invoice)}`
552
- );
553
- }
554
- /**
555
- * Resolve a Lightning Address (user@domain.com) to check if it exists
556
- * and get min/max sendable amounts.
557
- *
558
- * @param amountMsat Optional: get a specific invoice for this amount (in millisatoshis)
559
- */
560
- async resolveAddress(address, amountMsat) {
561
- let path = `/api/v2/lightning/resolve-ln-address?lnAddress=${encodeURIComponent(address)}`;
562
- if (amountMsat !== void 0) path += `&amount=${amountMsat}`;
563
- return this.client.get(path);
564
- }
565
- /**
566
- * Resolve an LNURL string to see its type (pay/withdraw/channel) and parameters.
567
- */
568
- async resolveLnurl(lnurl) {
569
- return this.client.get(
570
- `/api/v2/lightning/resolve-lnurl?lnurl=${encodeURIComponent(lnurl)}`
571
- );
572
- }
573
545
  };
574
546
 
575
547
  // src/resources/webhooks.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/errors.ts","../src/sanitize.ts","../src/resources/account.ts","../src/resources/transactions.ts","../src/resources/lightning.ts","../src/resources/webhooks.ts","../src/resources/rates.ts","../src/resources/fiat.ts","../src/utils.ts"],"sourcesContent":["import { HttpClient } from \"./client.js\";\nimport { AccountResource } from \"./resources/account.js\";\nimport { TransactionsResource } from \"./resources/transactions.js\";\nimport { LightningResource } from \"./resources/lightning.js\";\nimport { WebhooksResource } from \"./resources/webhooks.js\";\nimport { RatesResource } from \"./resources/rates.js\";\nimport { FiatResource } from \"./resources/fiat.js\";\nimport type { NeutronConfig } from \"./types.js\";\n\n/**\n * Neutron SDK — Bitcoin Lightning, stablecoins, and fiat payments.\n *\n * @example\n * import { Neutron } from \"neutron-sdk\";\n *\n * const neutron = new Neutron({\n * apiKey: process.env.NEUTRON_API_KEY!,\n * apiSecret: process.env.NEUTRON_API_SECRET!,\n * });\n *\n * // Check balances\n * const wallets = await neutron.account.wallets();\n *\n * // Create a Lightning invoice\n * const invoice = await neutron.lightning.createInvoice({ amountSats: 10000 });\n *\n * // Send to a Lightning Address\n * const txn = await neutron.lightning.payAddress(\"alice@getalby.com\", { amountSats: 5000 });\n * await neutron.transactions.confirm(txn.txnId);\n */\nexport class Neutron {\n /** Account info, wallets, and deposit addresses */\n readonly account: AccountResource;\n /** Create, confirm, list, and track transactions */\n readonly transactions: TransactionsResource;\n /** Lightning invoices, payments, and utilities */\n readonly lightning: LightningResource;\n /** Webhook management */\n readonly webhooks: WebhooksResource;\n /** BTC exchange rates */\n readonly rates: RatesResource;\n /** Fiat payouts and bank lookups */\n readonly fiat: FiatResource;\n\n private readonly client: HttpClient;\n\n constructor(config: NeutronConfig) {\n this.client = new HttpClient(config);\n this.account = new AccountResource(this.client);\n this.transactions = new TransactionsResource(this.client);\n this.lightning = new LightningResource(this.client);\n this.webhooks = new WebhooksResource(this.client);\n this.rates = new RatesResource(this.client);\n this.fiat = new FiatResource(this.client);\n }\n\n /**\n * Explicitly authenticate and verify credentials.\n * Usually not needed — the SDK auto-authenticates on first request.\n */\n async authenticate() {\n return this.client.authenticate();\n }\n\n /**\n * Verify a webhook signature. Static method — no client instance needed.\n *\n * @example\n * const event = Neutron.verifyWebhook(req.body, req.headers[\"x-neutronpay-signature\"], secret);\n */\n static verifyWebhook(body: string | Buffer, signature: string | undefined | null, secret: string) {\n return WebhooksResource.verifySignature(body, signature, secret);\n }\n}\n\n// ── Exports ─────────────────────────────────────────────────\n\nexport { HttpClient } from \"./client.js\";\nexport { AccountResource } from \"./resources/account.js\";\nexport { TransactionsResource } from \"./resources/transactions.js\";\nexport { LightningResource } from \"./resources/lightning.js\";\nexport { WebhooksResource } from \"./resources/webhooks.js\";\nexport { RatesResource } from \"./resources/rates.js\";\nexport { FiatResource } from \"./resources/fiat.js\";\nexport type { FiatPayoutParams } from \"./resources/fiat.js\";\n\nexport { sanitizePathParam } from \"./sanitize.js\";\n\nexport {\n NeutronError,\n NeutronApiError,\n NeutronAuthError,\n NeutronTimeoutError,\n NeutronValidationError,\n} from \"./errors.js\";\n\nexport {\n satsToBtc,\n btcToSats,\n formatSats,\n formatBtc,\n Currency,\n PaymentMethod,\n TransactionStates,\n FinalStates,\n Chain,\n} from \"./utils.js\";\n\nexport type {\n Currency as CurrencyType,\n PaymentMethodType,\n} from \"./utils.js\";\n\nexport type {\n NeutronConfig,\n AuthResponse,\n Account,\n Wallet,\n Transaction,\n TransactionState,\n TransactionSide,\n PaymentMethod as PaymentMethodString,\n CreateTransactionRequest,\n ListTransactionsParams,\n CreateInvoiceParams,\n LightningInvoice,\n DecodedInvoice,\n LightningAddressInfo,\n LnurlInfo,\n BtcAddress,\n UsdtAddress,\n Webhook,\n CreateWebhookParams,\n UpdateWebhookParams,\n ExchangeRates,\n FiatInstitution,\n KycInfo,\n SourceOfFunds,\n ApiResponse,\n} from \"./types.js\";\n","import crypto from \"crypto\";\nimport type { NeutronConfig, AuthResponse } from \"./types.js\";\nimport {\n NeutronApiError,\n NeutronAuthError,\n NeutronTimeoutError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://enapi.npay.live\";\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst TOKEN_REFRESH_BUFFER_MS = 60_000; // refresh 1 min before expiry\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly apiSecret: string;\n readonly baseUrl: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly debug: boolean;\n\n private accessToken: string | null = null;\n private accountId: string | null = null;\n private tokenExpiry: number = 0;\n\n constructor(config: NeutronConfig) {\n if (!config.apiKey) throw new NeutronAuthError(\"apiKey is required\");\n if (!config.apiSecret) throw new NeutronAuthError(\"apiSecret is required\");\n\n this.apiKey = config.apiKey;\n this.apiSecret = config.apiSecret;\n this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.debug = config.debug ?? false;\n }\n\n private log(message: string, data?: any): void {\n if (!this.debug) return;\n const ts = new Date().toISOString();\n const extra = data ? ` ${JSON.stringify(data)}` : \"\";\n console.error(`[neutron-sdk ${ts}] ${message}${extra}`);\n }\n\n // ── Auth ──────────────────────────────────────────────\n\n private generateSignature(payload: string): string {\n const stringToSign = `${this.apiKey}&payload=${payload}`;\n return crypto\n .createHmac(\"sha256\", this.apiSecret)\n .update(stringToSign)\n .digest(\"hex\");\n }\n\n private get isTokenValid(): boolean {\n return !!(\n this.accessToken &&\n this.accountId &&\n Date.now() < this.tokenExpiry - TOKEN_REFRESH_BUFFER_MS\n );\n }\n\n async authenticate(): Promise<AuthResponse> {\n const payload = JSON.stringify({ test: \"auth\" });\n const signature = this.generateSignature(payload);\n\n const response = await this.rawFetch(\n `${this.baseUrl}/api/v2/authentication/token-signature`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n \"X-Api-Signature\": signature,\n },\n body: payload,\n }\n );\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as Record<string, any>;\n throw new NeutronAuthError(\n body.error || body.message || `Authentication failed (${response.status})`\n );\n }\n\n const raw = (await response.json()) as any;\n // API wraps auth response in { data: { ... } }\n const result: AuthResponse = raw.data ?? raw;\n this.accountId = result.accountId;\n this.accessToken = result.accessToken;\n this.tokenExpiry = typeof result.expiredAt === \"number\"\n ? result.expiredAt\n : new Date(result.expiredAt).getTime();\n\n return result;\n this.log(\"Authenticated\", { accountId: this.accountId });\n }\n\n private async ensureAuth(): Promise<void> {\n if (!this.isTokenValid) {\n await this.authenticate();\n }\n }\n\n getAccountId(): string {\n if (!this.accountId) {\n throw new NeutronAuthError(\"Not authenticated. Call a method first or use neutron.account.get().\");\n }\n return this.accountId;\n }\n\n async ensureAuthAndGetAccountId(): Promise<string> {\n await this.ensureAuth();\n return this.accountId!;\n }\n\n // ── HTTP ──────────────────────────────────────────────\n\n private async rawFetch(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n throw new NeutronTimeoutError(this.timeout);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async request<T = any>(method: string, path: string, body?: any): Promise<T> {\n await this.ensureAuth();\n\n let lastError: any;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n // Exponential backoff: 1s, 2s, 4s...\n await new Promise((r) => setTimeout(r, Math.pow(2, attempt - 1) * 1000));\n\n // Re-auth if token might have expired during retries\n if (!this.isTokenValid) await this.authenticate();\n }\n\n const url = `${this.baseUrl}${path}`;\n this.log(`${method} ${path}`);\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.accessToken}`,\n };\n if (body) headers[\"Content-Type\"] = \"application/json\";\n\n const response = await this.rawFetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (response.ok) {\n return (await response.json()) as T;\n }\n\n const errorBody = await response.json().catch(() => ({}));\n const apiError = new NeutronApiError(response.status, errorBody);\n\n // Re-authenticate on 401 and retry\n if (response.status === 401 && attempt < this.maxRetries) {\n this.accessToken = null;\n lastError = apiError;\n continue;\n }\n\n // Retry on 5xx and 429\n if (apiError.isRetryable && attempt < this.maxRetries) {\n lastError = apiError;\n continue;\n }\n\n throw apiError;\n }\n\n throw lastError;\n }\n\n async get<T = any>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T = any>(path: string, body?: any): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T = any>(path: string, body?: any): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async del<T = any>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","/**\n * Base error for all Neutron SDK errors.\n */\nexport class NeutronError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NeutronError\";\n }\n}\n\n/**\n * Thrown when the API returns an error response (4xx/5xx).\n */\nexport class NeutronApiError extends NeutronError {\n /** HTTP status code */\n readonly status: number;\n /** Neutron error code (e.g. \"2005\") */\n readonly code: string | undefined;\n /** Raw error body from the API */\n readonly body: any;\n\n constructor(status: number, body: any) {\n const message = body?.error || body?.message || `API error ${status}`;\n super(message);\n this.name = \"NeutronApiError\";\n this.status = status;\n this.code = body?.code;\n this.body = body;\n }\n\n /** True if this is a rate limit error (429) */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n /** True if this is an auth error (401/403) */\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n /** True if retrying might help (5xx, 429) */\n get isRetryable(): boolean {\n return this.status === 429 || this.status >= 500;\n }\n}\n\n/**\n * Thrown when authentication fails.\n */\nexport class NeutronAuthError extends NeutronError {\n constructor(message: string = \"Authentication failed. Check your API key and secret.\") {\n super(message);\n this.name = \"NeutronAuthError\";\n }\n}\n\n/**\n * Thrown when a request times out.\n */\nexport class NeutronTimeoutError extends NeutronError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`);\n this.name = \"NeutronTimeoutError\";\n }\n}\n\n/**\n * Thrown for SDK usage errors (bad params, missing fields).\n */\nexport class NeutronValidationError extends NeutronError {\n constructor(message: string) {\n super(message);\n this.name = \"NeutronValidationError\";\n }\n}\n","import { NeutronValidationError } from \"./errors.js\";\n\n/**\n * Sanitize a path parameter to prevent path traversal and injection.\n * Only allows alphanumeric characters, hyphens, underscores, and dots.\n */\nexport function sanitizePathParam(value: string, name: string): string {\n if (!value || typeof value !== \"string\") {\n throw new NeutronValidationError(`${name} is required and must be a non-empty string.`);\n }\n\n // Strip any path traversal or special characters\n const sanitized = value.replace(/[^a-zA-Z0-9\\-_.]/g, \"\");\n\n if (sanitized !== value) {\n throw new NeutronValidationError(\n `${name} contains invalid characters. Only alphanumeric, hyphens, underscores, and dots are allowed.`\n );\n }\n\n if (sanitized.includes(\"..\")) {\n throw new NeutronValidationError(`${name} cannot contain path traversal sequences.`);\n }\n\n return sanitized;\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { Account, Wallet } from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class AccountResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Get account info: display name, status, country, timezone.\n */\n async get(): Promise<Account> {\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}`);\n return (res.data ?? res) as Account;\n }\n\n /**\n * List all wallets with balances (BTC, USDT, fiat).\n */\n async wallets(): Promise<Wallet[]> {\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}/wallet/`);\n return res.data ?? res;\n }\n\n /**\n * Get a specific wallet by ID.\n */\n async wallet(walletId: string): Promise<Wallet> {\n sanitizePathParam(walletId, \"walletId\");\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}/wallet/${walletId}`);\n return (res.data ?? res) as Wallet;\n }\n\n /**\n * Get your Bitcoin on-chain deposit address (static, reusable).\n */\n async btcAddress(): Promise<{ address: string }> {\n const raw = await this.client.get(`/api/v2/account/onchain-address`);\n const data = raw?.data ?? raw;\n return { address: data.staticOnchainAddress };\n }\n\n /**\n * Get your USDT deposit address.\n * @param chain \"TRON\" (default, recommended) or \"ETH\"\n */\n async usdtAddress(chain: \"TRON\" | \"ETH\" = \"TRON\"): Promise<{ address: string; chain: string }> {\n const raw = await this.client.get(\n `/api/v2/account/stablecoin-onchain-address?walletCcy=USDT&chainId=${chain}`\n );\n const data = raw?.data ?? raw;\n return {\n address: data.staticStablecoinOnchainAddress || data.staticOnchainAddress,\n chain,\n };\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type {\n Transaction,\n CreateTransactionRequest,\n ListTransactionsParams,\n} from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class TransactionsResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Create a transaction (returns a quote). Call `.confirm()` to execute.\n *\n * @example\n * // Lightning receive (create invoice)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: {} },\n * destReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: 0.0001, reqDetails: {} },\n * });\n *\n * @example\n * // Lightning send (pay invoice)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"neutronpay\" },\n * destReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: { paymentRequest: \"lnbc...\" } },\n * });\n *\n * @example\n * // Internal swap (BTC → USDT)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: 0.001, reqDetails: {} },\n * destReq: { ccy: \"USDT\", method: \"neutronpay\", reqDetails: {} },\n * });\n */\n async create(params: CreateTransactionRequest): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, params);\n }\n\n /**\n * Confirm a quoted transaction to execute it.\n * After confirmation, Lightning invoices become payable and sends are dispatched.\n */\n async confirm(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.put<Transaction>(`/api/v2/transaction/${txnId}/confirm`);\n }\n\n /**\n * Get transaction status and details.\n */\n async get(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.get<Transaction>(`/api/v2/transaction/${txnId}`);\n }\n\n /**\n * List transactions with optional filters.\n *\n * @example\n * const completed = await neutron.transactions.list({ status: \"completed\", limit: 10 });\n */\n async list(params?: ListTransactionsParams): Promise<Transaction[]> {\n const qs = new URLSearchParams();\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null) qs.append(k, String(v));\n }\n }\n const query = qs.toString();\n const res = await this.client.get(`/api/v2/transaction${query ? `?${query}` : \"\"}`);\n return res.data ?? res;\n }\n\n /**\n * Cancel a quoted (unconfirmed) transaction.\n */\n async cancel(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.put<Transaction>(`/api/v2/transaction/${txnId}/cancel`);\n }\n\n /**\n * Wait for a transaction to reach a final state. Polls at the given interval.\n *\n * @param txnId Transaction ID\n * @param options.intervalMs Polling interval in ms (default: 3000)\n * @param options.timeoutMs Max wait time in ms (default: 300000 = 5 min)\n * @param options.onStateChange Callback fired on each state change\n * @returns The transaction in a final state\n *\n * @example\n * const txn = await neutron.transactions.waitForCompletion(txnId, {\n * onStateChange: (state) => console.log(\"State:\", state),\n * });\n */\n async waitForCompletion(\n txnId: string,\n options?: {\n intervalMs?: number;\n timeoutMs?: number;\n onStateChange?: (state: string, txn: Transaction) => void;\n }\n ): Promise<Transaction> {\n const FINAL_STATES = [\"completed\", \"failed\", \"expired\", \"rejected\", \"error\", \"usercanceled\"];\n const interval = options?.intervalMs ?? 3000;\n const timeout = options?.timeoutMs ?? 300_000;\n const start = Date.now();\n let lastState = \"\";\n\n while (Date.now() - start < timeout) {\n const txn = await this.get(txnId);\n\n if (txn.txnState !== lastState) {\n lastState = txn.txnState;\n options?.onStateChange?.(txn.txnState, txn);\n }\n\n if (FINAL_STATES.includes(txn.txnState)) {\n return txn;\n }\n\n await new Promise((r) => setTimeout(r, interval));\n }\n\n throw new Error(`Transaction ${txnId} did not complete within ${timeout}ms`);\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type {\n CreateInvoiceParams,\n LightningInvoice,\n DecodedInvoice,\n LightningAddressInfo,\n LnurlInfo,\n Transaction,\n} from \"../types.js\";\nimport { NeutronValidationError } from \"../errors.js\";\n\nexport class LightningResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Create a Lightning invoice to receive Bitcoin. Auto-confirms — ready to pay immediately.\n *\n * @example\n * const invoice = await neutron.lightning.createInvoice({ amountSats: 10000 });\n * console.log(invoice.invoice); // \"lnbc100u1p...\"\n * console.log(invoice.qrPageUrl); // hosted QR code page\n *\n * @example\n * const invoice = await neutron.lightning.createInvoice({\n * amountBtc: 0.001,\n * memo: \"Order #1234\",\n * extRefId: \"order-1234\",\n * });\n */\n async createInvoice(params: CreateInvoiceParams): Promise<LightningInvoice> {\n let btcAmount: number;\n\n if (params.amountSats !== undefined && params.amountBtc !== undefined) {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc, not both.\");\n }\n if (params.amountSats !== undefined) {\n if (params.amountSats <= 0) throw new NeutronValidationError(\"amountSats must be positive.\");\n btcAmount = params.amountSats / 100_000_000;\n } else if (params.amountBtc !== undefined) {\n if (params.amountBtc <= 0) throw new NeutronValidationError(\"amountBtc must be positive.\");\n btcAmount = params.amountBtc;\n } else {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc.\");\n }\n\n // Create\n const txn = await this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: {} },\n destReq: {\n ccy: \"BTC\",\n method: \"neutronpay\",\n amtRequested: btcAmount,\n reqDetails: {},\n },\n });\n\n // Auto-confirm\n const confirmed = await this.client.put<Transaction>(\n `/api/v2/transaction/${txn.txnId}/confirm`\n );\n\n return {\n txnId: confirmed.txnId,\n invoice: confirmed.sourceReq?.reqDetails?.paymentRequest ?? \"\",\n qrPageUrl: confirmed.sourceReq?.reqDetails?.invoicePageUrl,\n amountBtc: btcAmount,\n amountSats: Math.round(btcAmount * 100_000_000),\n status: confirmed.txnState,\n };\n }\n\n /**\n * Pay a Lightning invoice (BOLT11).\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to send.\n *\n * @example\n * const txn = await neutron.lightning.payInvoice(\"lnbc100u1p...\");\n * // Review fees: txn.sourceReq.neutronpayFees\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payInvoice(invoice: string, extRefId?: string): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId,\n sourceReq: { ccy: \"BTC\", method: \"neutronpay\" },\n destReq: {\n ccy: \"BTC\",\n method: \"lightning\",\n reqDetails: { paymentRequest: invoice },\n },\n });\n }\n\n /**\n * Send to a Lightning Address (user@domain.com).\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to send.\n *\n * @example\n * const txn = await neutron.lightning.payAddress(\"alice@getalby.com\", { amountSats: 5000 });\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payAddress(\n address: string,\n params: { amountSats?: number; amountBtc?: number; extRefId?: string }\n ): Promise<Transaction> {\n let btcAmount: number;\n if (params.amountSats !== undefined) {\n btcAmount = params.amountSats / 100_000_000;\n } else if (params.amountBtc !== undefined) {\n btcAmount = params.amountBtc;\n } else {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc.\");\n }\n\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: btcAmount },\n destReq: {\n ccy: \"BTC\",\n method: \"lnurl\",\n reqDetails: { lnurl: address },\n },\n });\n }\n\n /**\n * Decode a BOLT11 invoice to inspect it before paying.\n * Returns amount, expiry, destination node, description, and payment status.\n */\n async decodeInvoice(invoice: string): Promise<DecodedInvoice> {\n return this.client.get<DecodedInvoice>(\n `/api/v2/lightning/invoice?invoice=${encodeURIComponent(invoice)}`\n );\n }\n\n /**\n * Resolve a Lightning Address (user@domain.com) to check if it exists\n * and get min/max sendable amounts.\n *\n * @param amountMsat Optional: get a specific invoice for this amount (in millisatoshis)\n */\n async resolveAddress(address: string, amountMsat?: number): Promise<LightningAddressInfo> {\n let path = `/api/v2/lightning/resolve-ln-address?lnAddress=${encodeURIComponent(address)}`;\n if (amountMsat !== undefined) path += `&amount=${amountMsat}`;\n return this.client.get<LightningAddressInfo>(path);\n }\n\n /**\n * Resolve an LNURL string to see its type (pay/withdraw/channel) and parameters.\n */\n async resolveLnurl(lnurl: string): Promise<LnurlInfo> {\n return this.client.get<LnurlInfo>(\n `/api/v2/lightning/resolve-lnurl?lnurl=${encodeURIComponent(lnurl)}`\n );\n }\n}\n","import crypto from \"crypto\";\nimport type { HttpClient } from \"../client.js\";\nimport type { Webhook, CreateWebhookParams, UpdateWebhookParams } from \"../types.js\";\nimport { NeutronValidationError } from \"../errors.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class WebhooksResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Register a webhook to receive transaction state change notifications.\n *\n * @example\n * const webhook = await neutron.webhooks.create({\n * callback: \"https://myapp.com/webhooks/neutron\",\n * secret: \"my-webhook-secret\",\n * });\n */\n async create(params: CreateWebhookParams): Promise<Webhook> {\n return this.client.post<Webhook>(`/api/v2/webhook`, params);\n }\n\n /**\n * List all registered webhooks.\n */\n async list(): Promise<Webhook[]> {\n const res = await this.client.get(`/api/v2/webhook`);\n return res.data ?? res;\n }\n\n /**\n * Update a webhook's callback URL or secret.\n */\n async update(webhookId: string, params: UpdateWebhookParams): Promise<Webhook> {\n sanitizePathParam(webhookId, \"webhookId\");\n return this.client.put<Webhook>(`/api/v2/webhook/${webhookId}`, params);\n }\n\n /**\n * Delete a webhook.\n */\n async delete(webhookId: string): Promise<void> {\n sanitizePathParam(webhookId, \"webhookId\");\n await this.client.del(`/api/v2/webhook/${webhookId}`);\n }\n\n /**\n * Verify a webhook signature from an incoming request.\n * Throws if the signature is invalid.\n *\n * @param body The raw request body (string or Buffer)\n * @param signature The `X-Neutronpay-Signature` header value\n * @param secret Your webhook secret\n * @returns The parsed event payload\n *\n * @example\n * // Express\n * app.post(\"/webhooks/neutron\", express.raw({ type: \"application/json\" }), (req, res) => {\n * try {\n * const event = Neutron.webhooks.verifySignature(\n * req.body,\n * req.headers[\"x-neutronpay-signature\"],\n * \"my-webhook-secret\"\n * );\n * // event is verified and safe to use\n * if (event.txnState === \"completed\") fulfillOrder(event.extRefId);\n * } catch (err) {\n * return res.status(401).send(\"Invalid signature\");\n * }\n * res.status(200).send(\"OK\");\n * });\n */\n static verifySignature(\n body: string | Buffer,\n signature: string | undefined | null,\n secret: string\n ): any {\n if (!signature) {\n throw new NeutronValidationError(\"Missing webhook signature header (X-Neutronpay-Signature)\");\n }\n if (!secret) {\n throw new NeutronValidationError(\"Webhook secret is required for verification\");\n }\n\n const bodyStr = typeof body === \"string\" ? body : body.toString(\"utf8\");\n\n const expected = crypto\n .createHmac(\"sha256\", secret)\n .update(bodyStr)\n .digest(\"hex\");\n\n const sigBuf = Buffer.from(signature);\n const expBuf = Buffer.from(expected);\n const isValid = sigBuf.length === expBuf.length && crypto.timingSafeEqual(sigBuf, expBuf);\n\n if (!isValid) {\n throw new NeutronValidationError(\"Invalid webhook signature\");\n }\n\n return JSON.parse(bodyStr);\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { ExchangeRates } from \"../types.js\";\n\nexport class RatesResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Get current BTC exchange rates against all supported currencies.\n *\n * @example\n * const rates = await neutron.rates.get();\n * console.log(rates); // { BTCUSD: 97500, BTCVND: 2437500000, ... }\n */\n async get(): Promise<ExchangeRates> {\n const res = await this.client.get(`/api/v2/rate`);\n return res.data ?? res;\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { FiatInstitution, Transaction, SourceOfFunds } from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport interface FiatPayoutParams {\n /** Source currency (e.g. \"BTC\") */\n sourceCcy: string;\n /** Amount from source (in BTC for Bitcoin) */\n sourceAmount: number;\n /** Destination fiat currency (e.g. \"VND\") */\n destCcy: string;\n /** Payment method (e.g. \"vnd-instant\") */\n destMethod: string;\n /** Bank account number */\n bankAcctNum: string;\n /** Bank code from `neutron.fiat.institutions()` */\n institutionCode: string;\n /** Recipient legal full name */\n recipientName: string;\n /** Recipient country code (e.g. \"VN\") */\n countryCode: string;\n /** \"individual\" or \"business\" (default: \"individual\") */\n kycType?: \"individual\" | \"business\";\n /** Source of funds declaration */\n sourceOfFunds?: SourceOfFunds;\n /** Your reference ID */\n extRefId?: string;\n}\n\nexport class FiatResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * List banks and financial institutions for a country.\n * Returns institution codes needed for fiat payouts.\n *\n * @example\n * const banks = await neutron.fiat.institutions(\"VN\");\n * // [{ code: \"970422\", name: \"MB Bank\" }, ...]\n */\n async institutions(countryCode: string): Promise<FiatInstitution[]> {\n sanitizePathParam(countryCode, \"countryCode\");\n const res = await this.client.get(\n `/api/v2/reference/fiat-institution/by-country/${countryCode}`\n );\n return res.data ?? res;\n }\n\n /**\n * Create a fiat payout transaction. Handles KYC and source of funds automatically.\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to execute.\n *\n * @example\n * const txn = await neutron.fiat.payout({\n * sourceCcy: \"BTC\",\n * sourceAmount: 0.001,\n * destCcy: \"VND\",\n * destMethod: \"vnd-instant\",\n * bankAcctNum: \"0123456789\",\n * institutionCode: \"970422\",\n * recipientName: \"LE VAN A\",\n * countryCode: \"VN\",\n * });\n * // Review rate: txn.fxRate\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payout(params: FiatPayoutParams): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: {\n ccy: params.sourceCcy,\n method: \"neutronpay\",\n amtRequested: params.sourceAmount,\n reqDetails: {},\n },\n destReq: {\n ccy: params.destCcy,\n method: params.destMethod,\n reqDetails: {\n bankAcctNum: params.bankAcctNum,\n institutionCode: params.institutionCode,\n },\n kyc: {\n type: params.kycType || \"individual\",\n details: {\n legalFullName: params.recipientName,\n countryCode: params.countryCode,\n },\n },\n },\n sourceOfFunds: params.sourceOfFunds ?? {\n purpose: 1,\n source: 5,\n relationship: 3,\n },\n });\n }\n}\n","// ── Satoshi / BTC conversion ────────────────────────────────\n\nconst SATS_PER_BTC = 100_000_000;\n\n/**\n * Convert satoshis to BTC.\n * @example satsToBtc(10000) // 0.0001\n */\nexport function satsToBtc(sats: number): number {\n return sats / SATS_PER_BTC;\n}\n\n/**\n * Convert BTC to satoshis.\n * @example btcToSats(0.0001) // 10000\n */\nexport function btcToSats(btc: number): number {\n return Math.round(btc * SATS_PER_BTC);\n}\n\n/**\n * Format a satoshi amount as a human-readable string.\n * @example formatSats(1500000) // \"1,500,000 sats\"\n * @example formatSats(100) // \"100 sats\"\n */\nexport function formatSats(sats: number): string {\n return `${sats.toLocaleString(\"en-US\")} sats`;\n}\n\n/**\n * Format a BTC amount with appropriate precision.\n * @example formatBtc(0.00015) // \"0.00015000 BTC\"\n */\nexport function formatBtc(btc: number): string {\n return `${btc.toFixed(8)} BTC`;\n}\n\n// ── Constants ───────────────────────────────────────────────\n\n/** Supported currencies */\nexport const Currency = {\n BTC: \"BTC\",\n USDT: \"USDT\",\n VND: \"VND\",\n USD: \"USD\",\n CAD: \"CAD\",\n NGN: \"NGN\",\n KES: \"KES\",\n GHS: \"GHS\",\n} as const;\n\nexport type Currency = (typeof Currency)[keyof typeof Currency];\n\n/** Payment methods for sourceReq/destReq */\nexport const PaymentMethod = {\n /** Internal Neutron wallet */\n NEUTRON: \"neutronpay\",\n /** Lightning Network (BOLT11 invoices) */\n LIGHTNING: \"lightning\",\n /** Lightning Address / LNURL */\n LNURL: \"lnurl\",\n /** Bitcoin on-chain */\n ON_CHAIN: \"on-chain\",\n /** USDT on TRON (TRC-20) */\n TRON: \"tron\",\n /** USDT on Ethereum (ERC-20) */\n ETH: \"eth\",\n /** Vietnamese Dong instant bank transfer */\n VND_INSTANT: \"vnd-instant\",\n} as const;\n\nexport type PaymentMethodType = (typeof PaymentMethod)[keyof typeof PaymentMethod];\n\n/** Transaction final states (terminal — won't change) */\nexport const FinalStates = [\n \"completed\",\n \"expired\",\n \"rejected\",\n \"error\",\n \"usercanceled\",\n] as const;\n\n/** All transaction states */\nexport const TransactionStates = {\n QUOTED: \"quoted\",\n USER_CONFIRMED: \"userconfirmed\",\n SRC_CREATED: \"srccreated\",\n SRC_SENT: \"srcsent\",\n SRC_INTENT: \"srcintent\",\n SRC_PEND_CONFIRM: \"srcpendconfirmfill\",\n SRC_CONFIRMED: \"srcconfirmfilled\",\n DEST_PEND_SENT: \"destpendsent\",\n DEST_SENT: \"destsent\",\n COMPLETED: \"completed\",\n EXPIRED: \"expired\",\n REJECTED: \"rejected\",\n ERROR: \"error\",\n USER_CANCELED: \"usercanceled\",\n} as const;\n\n/** USDT blockchain options */\nexport const Chain = {\n TRON: \"TRON\",\n ETH: \"ETH\",\n} as const;\n"],"mappings":"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","names":["crypto","import_crypto","crypto"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/errors.ts","../src/sanitize.ts","../src/resources/account.ts","../src/resources/transactions.ts","../src/resources/lightning.ts","../src/resources/webhooks.ts","../src/resources/rates.ts","../src/resources/fiat.ts","../src/utils.ts"],"sourcesContent":["import { HttpClient } from \"./client.js\";\nimport { AccountResource } from \"./resources/account.js\";\nimport { TransactionsResource } from \"./resources/transactions.js\";\nimport { LightningResource } from \"./resources/lightning.js\";\nimport { WebhooksResource } from \"./resources/webhooks.js\";\nimport { RatesResource } from \"./resources/rates.js\";\nimport { FiatResource } from \"./resources/fiat.js\";\nimport type { NeutronConfig } from \"./types.js\";\n\n/**\n * Neutron SDK — Bitcoin Lightning, stablecoins, and fiat payments.\n *\n * @example\n * import { Neutron } from \"neutron-sdk\";\n *\n * const neutron = new Neutron({\n * apiKey: process.env.NEUTRON_API_KEY!,\n * apiSecret: process.env.NEUTRON_API_SECRET!,\n * });\n *\n * // Check balances\n * const wallets = await neutron.account.wallets();\n *\n * // Create a Lightning invoice\n * const invoice = await neutron.lightning.createInvoice({ amountSats: 10000 });\n *\n * // Send to a Lightning Address\n * const txn = await neutron.lightning.payAddress(\"alice@getalby.com\", { amountSats: 5000 });\n * await neutron.transactions.confirm(txn.txnId);\n */\nexport class Neutron {\n /** Account info, wallets, and deposit addresses */\n readonly account: AccountResource;\n /** Create, confirm, list, and track transactions */\n readonly transactions: TransactionsResource;\n /** Lightning invoices, payments, and utilities */\n readonly lightning: LightningResource;\n /** Webhook management */\n readonly webhooks: WebhooksResource;\n /** BTC exchange rates */\n readonly rates: RatesResource;\n /** Fiat payouts and bank lookups */\n readonly fiat: FiatResource;\n\n private readonly client: HttpClient;\n\n constructor(config: NeutronConfig) {\n this.client = new HttpClient(config);\n this.account = new AccountResource(this.client);\n this.transactions = new TransactionsResource(this.client);\n this.lightning = new LightningResource(this.client);\n this.webhooks = new WebhooksResource(this.client);\n this.rates = new RatesResource(this.client);\n this.fiat = new FiatResource(this.client);\n }\n\n /**\n * Explicitly authenticate and verify credentials.\n * Usually not needed — the SDK auto-authenticates on first request.\n */\n async authenticate() {\n return this.client.authenticate();\n }\n\n /**\n * Verify a webhook signature. Static method — no client instance needed.\n *\n * @example\n * const event = Neutron.verifyWebhook(req.body, req.headers[\"x-neutronpay-signature\"], secret);\n */\n static verifyWebhook(body: string | Buffer, signature: string | undefined | null, secret: string) {\n return WebhooksResource.verifySignature(body, signature, secret);\n }\n}\n\n// ── Exports ─────────────────────────────────────────────────\n\nexport { HttpClient } from \"./client.js\";\nexport { AccountResource } from \"./resources/account.js\";\nexport { TransactionsResource } from \"./resources/transactions.js\";\nexport { LightningResource } from \"./resources/lightning.js\";\nexport { WebhooksResource } from \"./resources/webhooks.js\";\nexport { RatesResource } from \"./resources/rates.js\";\nexport { FiatResource } from \"./resources/fiat.js\";\nexport type { FiatPayoutParams } from \"./resources/fiat.js\";\n\nexport { sanitizePathParam } from \"./sanitize.js\";\n\nexport {\n NeutronError,\n NeutronApiError,\n NeutronAuthError,\n NeutronTimeoutError,\n NeutronValidationError,\n} from \"./errors.js\";\n\nexport {\n satsToBtc,\n btcToSats,\n formatSats,\n formatBtc,\n Currency,\n PaymentMethod,\n TransactionStates,\n FinalStates,\n Chain,\n} from \"./utils.js\";\n\nexport type {\n Currency as CurrencyType,\n PaymentMethodType,\n} from \"./utils.js\";\n\nexport type {\n NeutronConfig,\n AuthResponse,\n Account,\n Wallet,\n Transaction,\n TransactionState,\n TransactionSide,\n PaymentMethod as PaymentMethodString,\n CreateTransactionRequest,\n ListTransactionsParams,\n CreateInvoiceParams,\n LightningInvoice,\n BtcAddress,\n UsdtAddress,\n Webhook,\n CreateWebhookParams,\n UpdateWebhookParams,\n ExchangeRates,\n FiatInstitution,\n KycInfo,\n SourceOfFunds,\n ApiResponse,\n} from \"./types.js\";\n","import crypto from \"crypto\";\nimport type { NeutronConfig, AuthResponse } from \"./types.js\";\nimport {\n NeutronApiError,\n NeutronAuthError,\n NeutronTimeoutError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.neutron.me\";\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst TOKEN_REFRESH_BUFFER_MS = 60_000; // refresh 1 min before expiry\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly apiSecret: string;\n readonly baseUrl: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly debug: boolean;\n\n private accessToken: string | null = null;\n private accountId: string | null = null;\n private tokenExpiry: number = 0;\n\n constructor(config: NeutronConfig) {\n if (!config.apiKey) throw new NeutronAuthError(\"apiKey is required\");\n if (!config.apiSecret) throw new NeutronAuthError(\"apiSecret is required\");\n\n this.apiKey = config.apiKey;\n this.apiSecret = config.apiSecret;\n this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.debug = config.debug ?? false;\n }\n\n private log(message: string, data?: any): void {\n if (!this.debug) return;\n const ts = new Date().toISOString();\n const extra = data ? ` ${JSON.stringify(data)}` : \"\";\n console.error(`[neutron-sdk ${ts}] ${message}${extra}`);\n }\n\n // ── Auth ──────────────────────────────────────────────\n\n private generateSignature(payload: string): string {\n const stringToSign = `${this.apiKey}&payload=${payload}`;\n return crypto\n .createHmac(\"sha256\", this.apiSecret)\n .update(stringToSign)\n .digest(\"hex\");\n }\n\n private get isTokenValid(): boolean {\n return !!(\n this.accessToken &&\n this.accountId &&\n Date.now() < this.tokenExpiry - TOKEN_REFRESH_BUFFER_MS\n );\n }\n\n async authenticate(): Promise<AuthResponse> {\n const payload = JSON.stringify({ test: \"auth\" });\n const signature = this.generateSignature(payload);\n\n const response = await this.rawFetch(\n `${this.baseUrl}/api/v2/authentication/token-signature`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n \"X-Api-Signature\": signature,\n },\n body: payload,\n }\n );\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as Record<string, any>;\n throw new NeutronAuthError(\n body.error || body.message || `Authentication failed (${response.status})`\n );\n }\n\n const raw = (await response.json()) as any;\n // API wraps auth response in { data: { ... } }\n const result: AuthResponse = raw.data ?? raw;\n this.accountId = result.accountId;\n this.accessToken = result.accessToken;\n this.tokenExpiry = typeof result.expiredAt === \"number\"\n ? result.expiredAt\n : new Date(result.expiredAt).getTime();\n\n return result;\n this.log(\"Authenticated\", { accountId: this.accountId });\n }\n\n private async ensureAuth(): Promise<void> {\n if (!this.isTokenValid) {\n await this.authenticate();\n }\n }\n\n getAccountId(): string {\n if (!this.accountId) {\n throw new NeutronAuthError(\"Not authenticated. Call a method first or use neutron.account.get().\");\n }\n return this.accountId;\n }\n\n async ensureAuthAndGetAccountId(): Promise<string> {\n await this.ensureAuth();\n return this.accountId!;\n }\n\n // ── HTTP ──────────────────────────────────────────────\n\n private async rawFetch(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n throw new NeutronTimeoutError(this.timeout);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async request<T = any>(method: string, path: string, body?: any): Promise<T> {\n await this.ensureAuth();\n\n let lastError: any;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n // Exponential backoff: 1s, 2s, 4s...\n await new Promise((r) => setTimeout(r, Math.pow(2, attempt - 1) * 1000));\n\n // Re-auth if token might have expired during retries\n if (!this.isTokenValid) await this.authenticate();\n }\n\n const url = `${this.baseUrl}${path}`;\n this.log(`${method} ${path}`);\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.accessToken}`,\n };\n if (body) headers[\"Content-Type\"] = \"application/json\";\n\n const response = await this.rawFetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (response.ok) {\n return (await response.json()) as T;\n }\n\n const errorBody = await response.json().catch(() => ({}));\n const apiError = new NeutronApiError(response.status, errorBody);\n\n // Re-authenticate on 401 and retry\n if (response.status === 401 && attempt < this.maxRetries) {\n this.accessToken = null;\n lastError = apiError;\n continue;\n }\n\n // Retry on 5xx and 429\n if (apiError.isRetryable && attempt < this.maxRetries) {\n lastError = apiError;\n continue;\n }\n\n throw apiError;\n }\n\n throw lastError;\n }\n\n async get<T = any>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T = any>(path: string, body?: any): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T = any>(path: string, body?: any): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async del<T = any>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","/**\n * Base error for all Neutron SDK errors.\n */\nexport class NeutronError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NeutronError\";\n }\n}\n\n/**\n * Thrown when the API returns an error response (4xx/5xx).\n */\nexport class NeutronApiError extends NeutronError {\n /** HTTP status code */\n readonly status: number;\n /** Neutron error code (e.g. \"2005\") */\n readonly code: string | undefined;\n /** Raw error body from the API */\n readonly body: any;\n\n constructor(status: number, body: any) {\n const message = body?.error || body?.message || `API error ${status}`;\n super(message);\n this.name = \"NeutronApiError\";\n this.status = status;\n this.code = body?.code;\n this.body = body;\n }\n\n /** True if this is a rate limit error (429) */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n /** True if this is an auth error (401/403) */\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n /** True if retrying might help (5xx, 429) */\n get isRetryable(): boolean {\n return this.status === 429 || this.status >= 500;\n }\n}\n\n/**\n * Thrown when authentication fails.\n */\nexport class NeutronAuthError extends NeutronError {\n constructor(message: string = \"Authentication failed. Check your API key and secret.\") {\n super(message);\n this.name = \"NeutronAuthError\";\n }\n}\n\n/**\n * Thrown when a request times out.\n */\nexport class NeutronTimeoutError extends NeutronError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`);\n this.name = \"NeutronTimeoutError\";\n }\n}\n\n/**\n * Thrown for SDK usage errors (bad params, missing fields).\n */\nexport class NeutronValidationError extends NeutronError {\n constructor(message: string) {\n super(message);\n this.name = \"NeutronValidationError\";\n }\n}\n","import { NeutronValidationError } from \"./errors.js\";\n\n/**\n * Sanitize a path parameter to prevent path traversal and injection.\n * Only allows alphanumeric characters, hyphens, underscores, and dots.\n */\nexport function sanitizePathParam(value: string, name: string): string {\n if (!value || typeof value !== \"string\") {\n throw new NeutronValidationError(`${name} is required and must be a non-empty string.`);\n }\n\n // Strip any path traversal or special characters\n const sanitized = value.replace(/[^a-zA-Z0-9\\-_.]/g, \"\");\n\n if (sanitized !== value) {\n throw new NeutronValidationError(\n `${name} contains invalid characters. Only alphanumeric, hyphens, underscores, and dots are allowed.`\n );\n }\n\n if (sanitized.includes(\"..\")) {\n throw new NeutronValidationError(`${name} cannot contain path traversal sequences.`);\n }\n\n return sanitized;\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { Account, Wallet } from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class AccountResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Get account info: display name, status, country, timezone.\n */\n async get(): Promise<Account> {\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}`);\n return (res.data ?? res) as Account;\n }\n\n /**\n * List all wallets with balances (BTC, USDT, fiat).\n */\n async wallets(): Promise<Wallet[]> {\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}/wallet/`);\n return res.data ?? res;\n }\n\n /**\n * Get a specific wallet by ID.\n */\n async wallet(walletId: string): Promise<Wallet> {\n sanitizePathParam(walletId, \"walletId\");\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}/wallet/${walletId}`);\n return (res.data ?? res) as Wallet;\n }\n\n /**\n * Get your Bitcoin on-chain deposit address (static, reusable).\n */\n async btcAddress(): Promise<{ address: string }> {\n const raw = await this.client.get(`/api/v2/account/onchain-address`);\n const data = raw?.data ?? raw;\n return { address: data.staticOnchainAddress };\n }\n\n /**\n * Get your USDT deposit address.\n * @param chain \"TRON\" (default, recommended) or \"ETH\"\n */\n async usdtAddress(chain: \"TRON\" | \"ETH\" = \"TRON\"): Promise<{ address: string; chain: string }> {\n const raw = await this.client.get(\n `/api/v2/account/stablecoin-onchain-address?walletCcy=USDT&chainId=${chain}`\n );\n const data = raw?.data ?? raw;\n return {\n address: data.staticStablecoinOnchainAddress || data.staticOnchainAddress,\n chain,\n };\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type {\n Transaction,\n CreateTransactionRequest,\n ListTransactionsParams,\n} from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class TransactionsResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Create a transaction (returns a quote). Call `.confirm()` to execute.\n *\n * @example\n * // Lightning receive (create invoice)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: {} },\n * destReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: 0.0001, reqDetails: {} },\n * });\n *\n * @example\n * // Lightning send (pay invoice)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"neutronpay\" },\n * destReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: { paymentRequest: \"lnbc...\" } },\n * });\n *\n * @example\n * // Internal swap (BTC → USDT)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: 0.001, reqDetails: {} },\n * destReq: { ccy: \"USDT\", method: \"neutronpay\", reqDetails: {} },\n * });\n */\n async create(params: CreateTransactionRequest): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, params);\n }\n\n /**\n * Confirm a quoted transaction to execute it.\n * After confirmation, Lightning invoices become payable and sends are dispatched.\n */\n async confirm(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.put<Transaction>(`/api/v2/transaction/${txnId}/confirm`);\n }\n\n /**\n * Get transaction status and details.\n */\n async get(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.get<Transaction>(`/api/v2/transaction/${txnId}`);\n }\n\n /**\n * List transactions with optional filters.\n *\n * @example\n * const completed = await neutron.transactions.list({ status: \"completed\", limit: 10 });\n */\n async list(params?: ListTransactionsParams): Promise<Transaction[]> {\n const qs = new URLSearchParams();\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null) qs.append(k, String(v));\n }\n }\n const query = qs.toString();\n const res = await this.client.get(`/api/v2/transaction${query ? `?${query}` : \"\"}`);\n return res.data ?? res;\n }\n\n /**\n * Cancel a quoted (unconfirmed) transaction.\n */\n async cancel(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.put<Transaction>(`/api/v2/transaction/${txnId}/cancel`);\n }\n\n /**\n * Wait for a transaction to reach a final state. Polls at the given interval.\n *\n * @param txnId Transaction ID\n * @param options.intervalMs Polling interval in ms (default: 3000)\n * @param options.timeoutMs Max wait time in ms (default: 300000 = 5 min)\n * @param options.onStateChange Callback fired on each state change\n * @returns The transaction in a final state\n *\n * @example\n * const txn = await neutron.transactions.waitForCompletion(txnId, {\n * onStateChange: (state) => console.log(\"State:\", state),\n * });\n */\n async waitForCompletion(\n txnId: string,\n options?: {\n intervalMs?: number;\n timeoutMs?: number;\n onStateChange?: (state: string, txn: Transaction) => void;\n }\n ): Promise<Transaction> {\n const FINAL_STATES = [\"completed\", \"failed\", \"expired\", \"rejected\", \"error\", \"usercanceled\"];\n const interval = options?.intervalMs ?? 3000;\n const timeout = options?.timeoutMs ?? 300_000;\n const start = Date.now();\n let lastState = \"\";\n\n while (Date.now() - start < timeout) {\n const txn = await this.get(txnId);\n\n if (txn.txnState !== lastState) {\n lastState = txn.txnState;\n options?.onStateChange?.(txn.txnState, txn);\n }\n\n if (FINAL_STATES.includes(txn.txnState)) {\n return txn;\n }\n\n await new Promise((r) => setTimeout(r, interval));\n }\n\n throw new Error(`Transaction ${txnId} did not complete within ${timeout}ms`);\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type {\n CreateInvoiceParams,\n LightningInvoice,\n Transaction,\n} from \"../types.js\";\nimport { NeutronValidationError } from \"../errors.js\";\n\nexport class LightningResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Create a Lightning invoice to receive Bitcoin. Auto-confirms — ready to pay immediately.\n *\n * @example\n * const invoice = await neutron.lightning.createInvoice({ amountSats: 10000 });\n * console.log(invoice.invoice); // \"lnbc100u1p...\"\n * console.log(invoice.qrPageUrl); // hosted QR code page\n *\n * @example\n * const invoice = await neutron.lightning.createInvoice({\n * amountBtc: 0.001,\n * memo: \"Order #1234\",\n * extRefId: \"order-1234\",\n * });\n */\n async createInvoice(params: CreateInvoiceParams): Promise<LightningInvoice> {\n let btcAmount: number;\n\n if (params.amountSats !== undefined && params.amountBtc !== undefined) {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc, not both.\");\n }\n if (params.amountSats !== undefined) {\n if (params.amountSats <= 0) throw new NeutronValidationError(\"amountSats must be positive.\");\n btcAmount = params.amountSats / 100_000_000;\n } else if (params.amountBtc !== undefined) {\n if (params.amountBtc <= 0) throw new NeutronValidationError(\"amountBtc must be positive.\");\n btcAmount = params.amountBtc;\n } else {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc.\");\n }\n\n // Create\n const txn = await this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: {} },\n destReq: {\n ccy: \"BTC\",\n method: \"neutronpay\",\n amtRequested: btcAmount,\n reqDetails: {},\n },\n });\n\n // Auto-confirm\n const confirmed = await this.client.put<Transaction>(\n `/api/v2/transaction/${txn.txnId}/confirm`\n );\n\n return {\n txnId: confirmed.txnId,\n invoice: confirmed.sourceReq?.reqDetails?.paymentRequest ?? \"\",\n qrPageUrl: confirmed.sourceReq?.reqDetails?.invoicePageUrl,\n amountBtc: btcAmount,\n amountSats: Math.round(btcAmount * 100_000_000),\n status: confirmed.txnState,\n };\n }\n\n /**\n * Pay a Lightning invoice (BOLT11).\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to send.\n *\n * @example\n * const txn = await neutron.lightning.payInvoice(\"lnbc100u1p...\");\n * // Review fees: txn.sourceReq.neutronpayFees\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payInvoice(invoice: string, extRefId?: string): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId,\n sourceReq: { ccy: \"BTC\", method: \"neutronpay\" },\n destReq: {\n ccy: \"BTC\",\n method: \"lightning\",\n reqDetails: { paymentRequest: invoice },\n },\n });\n }\n\n /**\n * Send to a Lightning Address (user@domain.com).\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to send.\n *\n * @example\n * const txn = await neutron.lightning.payAddress(\"alice@getalby.com\", { amountSats: 5000 });\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payAddress(\n address: string,\n params: { amountSats?: number; amountBtc?: number; extRefId?: string }\n ): Promise<Transaction> {\n let btcAmount: number;\n if (params.amountSats !== undefined) {\n btcAmount = params.amountSats / 100_000_000;\n } else if (params.amountBtc !== undefined) {\n btcAmount = params.amountBtc;\n } else {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc.\");\n }\n\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: btcAmount },\n destReq: {\n ccy: \"BTC\",\n method: \"lnurl\",\n reqDetails: { lnurl: address },\n },\n });\n }\n\n}\n","import crypto from \"crypto\";\nimport type { HttpClient } from \"../client.js\";\nimport type { Webhook, CreateWebhookParams, UpdateWebhookParams } from \"../types.js\";\nimport { NeutronValidationError } from \"../errors.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class WebhooksResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Register a webhook to receive transaction state change notifications.\n *\n * @example\n * const webhook = await neutron.webhooks.create({\n * callback: \"https://myapp.com/webhooks/neutron\",\n * secret: \"my-webhook-secret\",\n * });\n */\n async create(params: CreateWebhookParams): Promise<Webhook> {\n return this.client.post<Webhook>(`/api/v2/webhook`, params);\n }\n\n /**\n * List all registered webhooks.\n */\n async list(): Promise<Webhook[]> {\n const res = await this.client.get(`/api/v2/webhook`);\n return res.data ?? res;\n }\n\n /**\n * Update a webhook's callback URL or secret.\n */\n async update(webhookId: string, params: UpdateWebhookParams): Promise<Webhook> {\n sanitizePathParam(webhookId, \"webhookId\");\n return this.client.put<Webhook>(`/api/v2/webhook/${webhookId}`, params);\n }\n\n /**\n * Delete a webhook.\n */\n async delete(webhookId: string): Promise<void> {\n sanitizePathParam(webhookId, \"webhookId\");\n await this.client.del(`/api/v2/webhook/${webhookId}`);\n }\n\n /**\n * Verify a webhook signature from an incoming request.\n * Throws if the signature is invalid.\n *\n * @param body The raw request body (string or Buffer)\n * @param signature The `X-Neutronpay-Signature` header value\n * @param secret Your webhook secret\n * @returns The parsed event payload\n *\n * @example\n * // Express\n * app.post(\"/webhooks/neutron\", express.raw({ type: \"application/json\" }), (req, res) => {\n * try {\n * const event = Neutron.webhooks.verifySignature(\n * req.body,\n * req.headers[\"x-neutronpay-signature\"],\n * \"my-webhook-secret\"\n * );\n * // event is verified and safe to use\n * if (event.txnState === \"completed\") fulfillOrder(event.extRefId);\n * } catch (err) {\n * return res.status(401).send(\"Invalid signature\");\n * }\n * res.status(200).send(\"OK\");\n * });\n */\n static verifySignature(\n body: string | Buffer,\n signature: string | undefined | null,\n secret: string\n ): any {\n if (!signature) {\n throw new NeutronValidationError(\"Missing webhook signature header (X-Neutronpay-Signature)\");\n }\n if (!secret) {\n throw new NeutronValidationError(\"Webhook secret is required for verification\");\n }\n\n const bodyStr = typeof body === \"string\" ? body : body.toString(\"utf8\");\n\n const expected = crypto\n .createHmac(\"sha256\", secret)\n .update(bodyStr)\n .digest(\"hex\");\n\n const sigBuf = Buffer.from(signature);\n const expBuf = Buffer.from(expected);\n const isValid = sigBuf.length === expBuf.length && crypto.timingSafeEqual(sigBuf, expBuf);\n\n if (!isValid) {\n throw new NeutronValidationError(\"Invalid webhook signature\");\n }\n\n return JSON.parse(bodyStr);\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { ExchangeRates } from \"../types.js\";\n\nexport class RatesResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Get current BTC exchange rates against all supported currencies.\n *\n * @example\n * const rates = await neutron.rates.get();\n * console.log(rates); // { BTCUSD: 97500, BTCVND: 2437500000, ... }\n */\n async get(): Promise<ExchangeRates> {\n const res = await this.client.get(`/api/v2/rate`);\n return res.data ?? res;\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { FiatInstitution, Transaction, SourceOfFunds } from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport interface FiatPayoutParams {\n /** Source currency (e.g. \"BTC\") */\n sourceCcy: string;\n /** Amount from source (in BTC for Bitcoin) */\n sourceAmount: number;\n /** Destination fiat currency (e.g. \"VND\") */\n destCcy: string;\n /** Payment method (e.g. \"vnd-instant\") */\n destMethod: string;\n /** Bank account number */\n bankAcctNum: string;\n /** Bank code from `neutron.fiat.institutions()` */\n institutionCode: string;\n /** Recipient legal full name */\n recipientName: string;\n /** Recipient country code (e.g. \"VN\") */\n countryCode: string;\n /** \"individual\" or \"business\" (default: \"individual\") */\n kycType?: \"individual\" | \"business\";\n /** Source of funds declaration */\n sourceOfFunds?: SourceOfFunds;\n /** Your reference ID */\n extRefId?: string;\n}\n\nexport class FiatResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * List banks and financial institutions for a country.\n * Returns institution codes needed for fiat payouts.\n *\n * @example\n * const banks = await neutron.fiat.institutions(\"VN\");\n * // [{ code: \"970422\", name: \"MB Bank\" }, ...]\n */\n async institutions(countryCode: string): Promise<FiatInstitution[]> {\n sanitizePathParam(countryCode, \"countryCode\");\n const res = await this.client.get(\n `/api/v2/reference/fiat-institution/by-country/${countryCode}`\n );\n return res.data ?? res;\n }\n\n /**\n * Create a fiat payout transaction. Handles KYC and source of funds automatically.\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to execute.\n *\n * @example\n * const txn = await neutron.fiat.payout({\n * sourceCcy: \"BTC\",\n * sourceAmount: 0.001,\n * destCcy: \"VND\",\n * destMethod: \"vnd-instant\",\n * bankAcctNum: \"0123456789\",\n * institutionCode: \"970422\",\n * recipientName: \"LE VAN A\",\n * countryCode: \"VN\",\n * });\n * // Review rate: txn.fxRate\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payout(params: FiatPayoutParams): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: {\n ccy: params.sourceCcy,\n method: \"neutronpay\",\n amtRequested: params.sourceAmount,\n reqDetails: {},\n },\n destReq: {\n ccy: params.destCcy,\n method: params.destMethod,\n reqDetails: {\n bankAcctNum: params.bankAcctNum,\n institutionCode: params.institutionCode,\n },\n kyc: {\n type: params.kycType || \"individual\",\n details: {\n legalFullName: params.recipientName,\n countryCode: params.countryCode,\n },\n },\n },\n sourceOfFunds: params.sourceOfFunds ?? {\n purpose: 1,\n source: 5,\n relationship: 3,\n },\n });\n }\n}\n","// ── Satoshi / BTC conversion ────────────────────────────────\n\nconst SATS_PER_BTC = 100_000_000;\n\n/**\n * Convert satoshis to BTC.\n * @example satsToBtc(10000) // 0.0001\n */\nexport function satsToBtc(sats: number): number {\n return sats / SATS_PER_BTC;\n}\n\n/**\n * Convert BTC to satoshis.\n * @example btcToSats(0.0001) // 10000\n */\nexport function btcToSats(btc: number): number {\n return Math.round(btc * SATS_PER_BTC);\n}\n\n/**\n * Format a satoshi amount as a human-readable string.\n * @example formatSats(1500000) // \"1,500,000 sats\"\n * @example formatSats(100) // \"100 sats\"\n */\nexport function formatSats(sats: number): string {\n return `${sats.toLocaleString(\"en-US\")} sats`;\n}\n\n/**\n * Format a BTC amount with appropriate precision.\n * @example formatBtc(0.00015) // \"0.00015000 BTC\"\n */\nexport function formatBtc(btc: number): string {\n return `${btc.toFixed(8)} BTC`;\n}\n\n// ── Constants ───────────────────────────────────────────────\n\n/** Supported currencies */\nexport const Currency = {\n BTC: \"BTC\",\n USDT: \"USDT\",\n VND: \"VND\",\n USD: \"USD\",\n CAD: \"CAD\",\n NGN: \"NGN\",\n KES: \"KES\",\n GHS: \"GHS\",\n} as const;\n\nexport type Currency = (typeof Currency)[keyof typeof Currency];\n\n/** Payment methods for sourceReq/destReq */\nexport const PaymentMethod = {\n /** Internal Neutron wallet */\n NEUTRON: \"neutronpay\",\n /** Lightning Network (BOLT11 invoices) */\n LIGHTNING: \"lightning\",\n /** Lightning Address / LNURL */\n LNURL: \"lnurl\",\n /** Bitcoin on-chain */\n ON_CHAIN: \"on-chain\",\n /** USDT on TRON (TRC-20) */\n TRON: \"tron\",\n /** USDT on Ethereum (ERC-20) */\n ETH: \"eth\",\n /** Vietnamese Dong instant bank transfer */\n VND_INSTANT: \"vnd-instant\",\n} as const;\n\nexport type PaymentMethodType = (typeof PaymentMethod)[keyof typeof PaymentMethod];\n\n/** Transaction final states (terminal — won't change) */\nexport const FinalStates = [\n \"completed\",\n \"expired\",\n \"rejected\",\n \"error\",\n \"usercanceled\",\n] as const;\n\n/** All transaction states */\nexport const TransactionStates = {\n QUOTED: \"quoted\",\n USER_CONFIRMED: \"userconfirmed\",\n SRC_CREATED: \"srccreated\",\n SRC_SENT: \"srcsent\",\n SRC_INTENT: \"srcintent\",\n SRC_PEND_CONFIRM: \"srcpendconfirmfill\",\n SRC_CONFIRMED: \"srcconfirmfilled\",\n DEST_PEND_SENT: \"destpendsent\",\n DEST_SENT: \"destsent\",\n COMPLETED: \"completed\",\n EXPIRED: \"expired\",\n REJECTED: \"rejected\",\n ERROR: \"error\",\n USER_CANCELED: \"usercanceled\",\n} as const;\n\n/** USDT blockchain options */\nexport const Chain = {\n TRON: \"TRON\",\n ETH: \"ETH\",\n} as const;\n"],"mappings":"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","names":["crypto","import_crypto","crypto"]}
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@ interface NeutronConfig {
3
3
  apiKey: string;
4
4
  /** Your Neutron API secret */
5
5
  apiSecret: string;
6
- /** API base URL (default: https://enapi.npay.live) */
6
+ /** API base URL (default: https://api.neutron.me) */
7
7
  baseUrl?: string;
8
8
  /** Request timeout in ms (default: 30000) */
9
9
  timeout?: number;
@@ -106,32 +106,6 @@ interface LightningInvoice {
106
106
  amountSats: number;
107
107
  status: TransactionState;
108
108
  }
109
- interface DecodedInvoice {
110
- amount?: number;
111
- amountMsat?: number;
112
- expiry?: number;
113
- destination?: string;
114
- description?: string;
115
- paymentHash?: string;
116
- status?: string;
117
- [key: string]: any;
118
- }
119
- interface LightningAddressInfo {
120
- tag?: string;
121
- callback?: string;
122
- minSendable?: number;
123
- maxSendable?: number;
124
- metadata?: string;
125
- [key: string]: any;
126
- }
127
- interface LnurlInfo {
128
- tag?: string;
129
- callback?: string;
130
- minSendable?: number;
131
- maxSendable?: number;
132
- k1?: string;
133
- [key: string]: any;
134
- }
135
109
  interface BtcAddress {
136
110
  staticOnchainAddress: string;
137
111
  accountId: string;
@@ -342,22 +316,6 @@ declare class LightningResource {
342
316
  amountBtc?: number;
343
317
  extRefId?: string;
344
318
  }): Promise<Transaction>;
345
- /**
346
- * Decode a BOLT11 invoice to inspect it before paying.
347
- * Returns amount, expiry, destination node, description, and payment status.
348
- */
349
- decodeInvoice(invoice: string): Promise<DecodedInvoice>;
350
- /**
351
- * Resolve a Lightning Address (user@domain.com) to check if it exists
352
- * and get min/max sendable amounts.
353
- *
354
- * @param amountMsat Optional: get a specific invoice for this amount (in millisatoshis)
355
- */
356
- resolveAddress(address: string, amountMsat?: number): Promise<LightningAddressInfo>;
357
- /**
358
- * Resolve an LNURL string to see its type (pay/withdraw/channel) and parameters.
359
- */
360
- resolveLnurl(lnurl: string): Promise<LnurlInfo>;
361
319
  }
362
320
 
363
321
  declare class WebhooksResource {
@@ -659,4 +617,4 @@ declare class Neutron {
659
617
  static verifyWebhook(body: string | Buffer, signature: string | undefined | null, secret: string): any;
660
618
  }
661
619
 
662
- export { type Account, AccountResource, type ApiResponse, type AuthResponse, type BtcAddress, Chain, type CreateInvoiceParams, type CreateTransactionRequest, type CreateWebhookParams, Currency, Currency as CurrencyType, type DecodedInvoice, type ExchangeRates, type FiatInstitution, type FiatPayoutParams, FiatResource, FinalStates, HttpClient, type KycInfo, type LightningAddressInfo, type LightningInvoice, LightningResource, type ListTransactionsParams, type LnurlInfo, Neutron, NeutronApiError, NeutronAuthError, type NeutronConfig, NeutronError, NeutronTimeoutError, NeutronValidationError, PaymentMethod, type PaymentMethod$1 as PaymentMethodString, type PaymentMethodType, RatesResource, type SourceOfFunds, type Transaction, type TransactionSide, type TransactionState, TransactionStates, TransactionsResource, type UpdateWebhookParams, type UsdtAddress, type Wallet, type Webhook, WebhooksResource, btcToSats, formatBtc, formatSats, sanitizePathParam, satsToBtc };
620
+ export { type Account, AccountResource, type ApiResponse, type AuthResponse, type BtcAddress, Chain, type CreateInvoiceParams, type CreateTransactionRequest, type CreateWebhookParams, Currency, Currency as CurrencyType, type ExchangeRates, type FiatInstitution, type FiatPayoutParams, FiatResource, FinalStates, HttpClient, type KycInfo, type LightningInvoice, LightningResource, type ListTransactionsParams, Neutron, NeutronApiError, NeutronAuthError, type NeutronConfig, NeutronError, NeutronTimeoutError, NeutronValidationError, PaymentMethod, type PaymentMethod$1 as PaymentMethodString, type PaymentMethodType, RatesResource, type SourceOfFunds, type Transaction, type TransactionSide, type TransactionState, TransactionStates, TransactionsResource, type UpdateWebhookParams, type UsdtAddress, type Wallet, type Webhook, WebhooksResource, btcToSats, formatBtc, formatSats, sanitizePathParam, satsToBtc };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ interface NeutronConfig {
3
3
  apiKey: string;
4
4
  /** Your Neutron API secret */
5
5
  apiSecret: string;
6
- /** API base URL (default: https://enapi.npay.live) */
6
+ /** API base URL (default: https://api.neutron.me) */
7
7
  baseUrl?: string;
8
8
  /** Request timeout in ms (default: 30000) */
9
9
  timeout?: number;
@@ -106,32 +106,6 @@ interface LightningInvoice {
106
106
  amountSats: number;
107
107
  status: TransactionState;
108
108
  }
109
- interface DecodedInvoice {
110
- amount?: number;
111
- amountMsat?: number;
112
- expiry?: number;
113
- destination?: string;
114
- description?: string;
115
- paymentHash?: string;
116
- status?: string;
117
- [key: string]: any;
118
- }
119
- interface LightningAddressInfo {
120
- tag?: string;
121
- callback?: string;
122
- minSendable?: number;
123
- maxSendable?: number;
124
- metadata?: string;
125
- [key: string]: any;
126
- }
127
- interface LnurlInfo {
128
- tag?: string;
129
- callback?: string;
130
- minSendable?: number;
131
- maxSendable?: number;
132
- k1?: string;
133
- [key: string]: any;
134
- }
135
109
  interface BtcAddress {
136
110
  staticOnchainAddress: string;
137
111
  accountId: string;
@@ -342,22 +316,6 @@ declare class LightningResource {
342
316
  amountBtc?: number;
343
317
  extRefId?: string;
344
318
  }): Promise<Transaction>;
345
- /**
346
- * Decode a BOLT11 invoice to inspect it before paying.
347
- * Returns amount, expiry, destination node, description, and payment status.
348
- */
349
- decodeInvoice(invoice: string): Promise<DecodedInvoice>;
350
- /**
351
- * Resolve a Lightning Address (user@domain.com) to check if it exists
352
- * and get min/max sendable amounts.
353
- *
354
- * @param amountMsat Optional: get a specific invoice for this amount (in millisatoshis)
355
- */
356
- resolveAddress(address: string, amountMsat?: number): Promise<LightningAddressInfo>;
357
- /**
358
- * Resolve an LNURL string to see its type (pay/withdraw/channel) and parameters.
359
- */
360
- resolveLnurl(lnurl: string): Promise<LnurlInfo>;
361
319
  }
362
320
 
363
321
  declare class WebhooksResource {
@@ -659,4 +617,4 @@ declare class Neutron {
659
617
  static verifyWebhook(body: string | Buffer, signature: string | undefined | null, secret: string): any;
660
618
  }
661
619
 
662
- export { type Account, AccountResource, type ApiResponse, type AuthResponse, type BtcAddress, Chain, type CreateInvoiceParams, type CreateTransactionRequest, type CreateWebhookParams, Currency, Currency as CurrencyType, type DecodedInvoice, type ExchangeRates, type FiatInstitution, type FiatPayoutParams, FiatResource, FinalStates, HttpClient, type KycInfo, type LightningAddressInfo, type LightningInvoice, LightningResource, type ListTransactionsParams, type LnurlInfo, Neutron, NeutronApiError, NeutronAuthError, type NeutronConfig, NeutronError, NeutronTimeoutError, NeutronValidationError, PaymentMethod, type PaymentMethod$1 as PaymentMethodString, type PaymentMethodType, RatesResource, type SourceOfFunds, type Transaction, type TransactionSide, type TransactionState, TransactionStates, TransactionsResource, type UpdateWebhookParams, type UsdtAddress, type Wallet, type Webhook, WebhooksResource, btcToSats, formatBtc, formatSats, sanitizePathParam, satsToBtc };
620
+ export { type Account, AccountResource, type ApiResponse, type AuthResponse, type BtcAddress, Chain, type CreateInvoiceParams, type CreateTransactionRequest, type CreateWebhookParams, Currency, Currency as CurrencyType, type ExchangeRates, type FiatInstitution, type FiatPayoutParams, FiatResource, FinalStates, HttpClient, type KycInfo, type LightningInvoice, LightningResource, type ListTransactionsParams, Neutron, NeutronApiError, NeutronAuthError, type NeutronConfig, NeutronError, NeutronTimeoutError, NeutronValidationError, PaymentMethod, type PaymentMethod$1 as PaymentMethodString, type PaymentMethodType, RatesResource, type SourceOfFunds, type Transaction, type TransactionSide, type TransactionState, TransactionStates, TransactionsResource, type UpdateWebhookParams, type UsdtAddress, type Wallet, type Webhook, WebhooksResource, btcToSats, formatBtc, formatSats, sanitizePathParam, satsToBtc };
package/dist/index.js CHANGED
@@ -56,7 +56,7 @@ var NeutronValidationError = class extends NeutronError {
56
56
  };
57
57
 
58
58
  // src/client.ts
59
- var DEFAULT_BASE_URL = "https://enapi.npay.live";
59
+ var DEFAULT_BASE_URL = "https://api.neutron.me";
60
60
  var DEFAULT_TIMEOUT = 3e4;
61
61
  var DEFAULT_MAX_RETRIES = 2;
62
62
  var TOKEN_REFRESH_BUFFER_MS = 6e4;
@@ -484,34 +484,6 @@ var LightningResource = class {
484
484
  }
485
485
  });
486
486
  }
487
- /**
488
- * Decode a BOLT11 invoice to inspect it before paying.
489
- * Returns amount, expiry, destination node, description, and payment status.
490
- */
491
- async decodeInvoice(invoice) {
492
- return this.client.get(
493
- `/api/v2/lightning/invoice?invoice=${encodeURIComponent(invoice)}`
494
- );
495
- }
496
- /**
497
- * Resolve a Lightning Address (user@domain.com) to check if it exists
498
- * and get min/max sendable amounts.
499
- *
500
- * @param amountMsat Optional: get a specific invoice for this amount (in millisatoshis)
501
- */
502
- async resolveAddress(address, amountMsat) {
503
- let path = `/api/v2/lightning/resolve-ln-address?lnAddress=${encodeURIComponent(address)}`;
504
- if (amountMsat !== void 0) path += `&amount=${amountMsat}`;
505
- return this.client.get(path);
506
- }
507
- /**
508
- * Resolve an LNURL string to see its type (pay/withdraw/channel) and parameters.
509
- */
510
- async resolveLnurl(lnurl) {
511
- return this.client.get(
512
- `/api/v2/lightning/resolve-lnurl?lnurl=${encodeURIComponent(lnurl)}`
513
- );
514
- }
515
487
  };
516
488
 
517
489
  // src/resources/webhooks.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/errors.ts","../src/sanitize.ts","../src/resources/account.ts","../src/resources/transactions.ts","../src/resources/lightning.ts","../src/resources/webhooks.ts","../src/resources/rates.ts","../src/resources/fiat.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import crypto from \"crypto\";\nimport type { NeutronConfig, AuthResponse } from \"./types.js\";\nimport {\n NeutronApiError,\n NeutronAuthError,\n NeutronTimeoutError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://enapi.npay.live\";\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst TOKEN_REFRESH_BUFFER_MS = 60_000; // refresh 1 min before expiry\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly apiSecret: string;\n readonly baseUrl: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly debug: boolean;\n\n private accessToken: string | null = null;\n private accountId: string | null = null;\n private tokenExpiry: number = 0;\n\n constructor(config: NeutronConfig) {\n if (!config.apiKey) throw new NeutronAuthError(\"apiKey is required\");\n if (!config.apiSecret) throw new NeutronAuthError(\"apiSecret is required\");\n\n this.apiKey = config.apiKey;\n this.apiSecret = config.apiSecret;\n this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.debug = config.debug ?? false;\n }\n\n private log(message: string, data?: any): void {\n if (!this.debug) return;\n const ts = new Date().toISOString();\n const extra = data ? ` ${JSON.stringify(data)}` : \"\";\n console.error(`[neutron-sdk ${ts}] ${message}${extra}`);\n }\n\n // ── Auth ──────────────────────────────────────────────\n\n private generateSignature(payload: string): string {\n const stringToSign = `${this.apiKey}&payload=${payload}`;\n return crypto\n .createHmac(\"sha256\", this.apiSecret)\n .update(stringToSign)\n .digest(\"hex\");\n }\n\n private get isTokenValid(): boolean {\n return !!(\n this.accessToken &&\n this.accountId &&\n Date.now() < this.tokenExpiry - TOKEN_REFRESH_BUFFER_MS\n );\n }\n\n async authenticate(): Promise<AuthResponse> {\n const payload = JSON.stringify({ test: \"auth\" });\n const signature = this.generateSignature(payload);\n\n const response = await this.rawFetch(\n `${this.baseUrl}/api/v2/authentication/token-signature`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n \"X-Api-Signature\": signature,\n },\n body: payload,\n }\n );\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as Record<string, any>;\n throw new NeutronAuthError(\n body.error || body.message || `Authentication failed (${response.status})`\n );\n }\n\n const raw = (await response.json()) as any;\n // API wraps auth response in { data: { ... } }\n const result: AuthResponse = raw.data ?? raw;\n this.accountId = result.accountId;\n this.accessToken = result.accessToken;\n this.tokenExpiry = typeof result.expiredAt === \"number\"\n ? result.expiredAt\n : new Date(result.expiredAt).getTime();\n\n return result;\n this.log(\"Authenticated\", { accountId: this.accountId });\n }\n\n private async ensureAuth(): Promise<void> {\n if (!this.isTokenValid) {\n await this.authenticate();\n }\n }\n\n getAccountId(): string {\n if (!this.accountId) {\n throw new NeutronAuthError(\"Not authenticated. Call a method first or use neutron.account.get().\");\n }\n return this.accountId;\n }\n\n async ensureAuthAndGetAccountId(): Promise<string> {\n await this.ensureAuth();\n return this.accountId!;\n }\n\n // ── HTTP ──────────────────────────────────────────────\n\n private async rawFetch(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n throw new NeutronTimeoutError(this.timeout);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async request<T = any>(method: string, path: string, body?: any): Promise<T> {\n await this.ensureAuth();\n\n let lastError: any;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n // Exponential backoff: 1s, 2s, 4s...\n await new Promise((r) => setTimeout(r, Math.pow(2, attempt - 1) * 1000));\n\n // Re-auth if token might have expired during retries\n if (!this.isTokenValid) await this.authenticate();\n }\n\n const url = `${this.baseUrl}${path}`;\n this.log(`${method} ${path}`);\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.accessToken}`,\n };\n if (body) headers[\"Content-Type\"] = \"application/json\";\n\n const response = await this.rawFetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (response.ok) {\n return (await response.json()) as T;\n }\n\n const errorBody = await response.json().catch(() => ({}));\n const apiError = new NeutronApiError(response.status, errorBody);\n\n // Re-authenticate on 401 and retry\n if (response.status === 401 && attempt < this.maxRetries) {\n this.accessToken = null;\n lastError = apiError;\n continue;\n }\n\n // Retry on 5xx and 429\n if (apiError.isRetryable && attempt < this.maxRetries) {\n lastError = apiError;\n continue;\n }\n\n throw apiError;\n }\n\n throw lastError;\n }\n\n async get<T = any>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T = any>(path: string, body?: any): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T = any>(path: string, body?: any): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async del<T = any>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","/**\n * Base error for all Neutron SDK errors.\n */\nexport class NeutronError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NeutronError\";\n }\n}\n\n/**\n * Thrown when the API returns an error response (4xx/5xx).\n */\nexport class NeutronApiError extends NeutronError {\n /** HTTP status code */\n readonly status: number;\n /** Neutron error code (e.g. \"2005\") */\n readonly code: string | undefined;\n /** Raw error body from the API */\n readonly body: any;\n\n constructor(status: number, body: any) {\n const message = body?.error || body?.message || `API error ${status}`;\n super(message);\n this.name = \"NeutronApiError\";\n this.status = status;\n this.code = body?.code;\n this.body = body;\n }\n\n /** True if this is a rate limit error (429) */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n /** True if this is an auth error (401/403) */\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n /** True if retrying might help (5xx, 429) */\n get isRetryable(): boolean {\n return this.status === 429 || this.status >= 500;\n }\n}\n\n/**\n * Thrown when authentication fails.\n */\nexport class NeutronAuthError extends NeutronError {\n constructor(message: string = \"Authentication failed. Check your API key and secret.\") {\n super(message);\n this.name = \"NeutronAuthError\";\n }\n}\n\n/**\n * Thrown when a request times out.\n */\nexport class NeutronTimeoutError extends NeutronError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`);\n this.name = \"NeutronTimeoutError\";\n }\n}\n\n/**\n * Thrown for SDK usage errors (bad params, missing fields).\n */\nexport class NeutronValidationError extends NeutronError {\n constructor(message: string) {\n super(message);\n this.name = \"NeutronValidationError\";\n }\n}\n","import { NeutronValidationError } from \"./errors.js\";\n\n/**\n * Sanitize a path parameter to prevent path traversal and injection.\n * Only allows alphanumeric characters, hyphens, underscores, and dots.\n */\nexport function sanitizePathParam(value: string, name: string): string {\n if (!value || typeof value !== \"string\") {\n throw new NeutronValidationError(`${name} is required and must be a non-empty string.`);\n }\n\n // Strip any path traversal or special characters\n const sanitized = value.replace(/[^a-zA-Z0-9\\-_.]/g, \"\");\n\n if (sanitized !== value) {\n throw new NeutronValidationError(\n `${name} contains invalid characters. Only alphanumeric, hyphens, underscores, and dots are allowed.`\n );\n }\n\n if (sanitized.includes(\"..\")) {\n throw new NeutronValidationError(`${name} cannot contain path traversal sequences.`);\n }\n\n return sanitized;\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { Account, Wallet } from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class AccountResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Get account info: display name, status, country, timezone.\n */\n async get(): Promise<Account> {\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}`);\n return (res.data ?? res) as Account;\n }\n\n /**\n * List all wallets with balances (BTC, USDT, fiat).\n */\n async wallets(): Promise<Wallet[]> {\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}/wallet/`);\n return res.data ?? res;\n }\n\n /**\n * Get a specific wallet by ID.\n */\n async wallet(walletId: string): Promise<Wallet> {\n sanitizePathParam(walletId, \"walletId\");\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}/wallet/${walletId}`);\n return (res.data ?? res) as Wallet;\n }\n\n /**\n * Get your Bitcoin on-chain deposit address (static, reusable).\n */\n async btcAddress(): Promise<{ address: string }> {\n const raw = await this.client.get(`/api/v2/account/onchain-address`);\n const data = raw?.data ?? raw;\n return { address: data.staticOnchainAddress };\n }\n\n /**\n * Get your USDT deposit address.\n * @param chain \"TRON\" (default, recommended) or \"ETH\"\n */\n async usdtAddress(chain: \"TRON\" | \"ETH\" = \"TRON\"): Promise<{ address: string; chain: string }> {\n const raw = await this.client.get(\n `/api/v2/account/stablecoin-onchain-address?walletCcy=USDT&chainId=${chain}`\n );\n const data = raw?.data ?? raw;\n return {\n address: data.staticStablecoinOnchainAddress || data.staticOnchainAddress,\n chain,\n };\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type {\n Transaction,\n CreateTransactionRequest,\n ListTransactionsParams,\n} from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class TransactionsResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Create a transaction (returns a quote). Call `.confirm()` to execute.\n *\n * @example\n * // Lightning receive (create invoice)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: {} },\n * destReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: 0.0001, reqDetails: {} },\n * });\n *\n * @example\n * // Lightning send (pay invoice)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"neutronpay\" },\n * destReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: { paymentRequest: \"lnbc...\" } },\n * });\n *\n * @example\n * // Internal swap (BTC → USDT)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: 0.001, reqDetails: {} },\n * destReq: { ccy: \"USDT\", method: \"neutronpay\", reqDetails: {} },\n * });\n */\n async create(params: CreateTransactionRequest): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, params);\n }\n\n /**\n * Confirm a quoted transaction to execute it.\n * After confirmation, Lightning invoices become payable and sends are dispatched.\n */\n async confirm(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.put<Transaction>(`/api/v2/transaction/${txnId}/confirm`);\n }\n\n /**\n * Get transaction status and details.\n */\n async get(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.get<Transaction>(`/api/v2/transaction/${txnId}`);\n }\n\n /**\n * List transactions with optional filters.\n *\n * @example\n * const completed = await neutron.transactions.list({ status: \"completed\", limit: 10 });\n */\n async list(params?: ListTransactionsParams): Promise<Transaction[]> {\n const qs = new URLSearchParams();\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null) qs.append(k, String(v));\n }\n }\n const query = qs.toString();\n const res = await this.client.get(`/api/v2/transaction${query ? `?${query}` : \"\"}`);\n return res.data ?? res;\n }\n\n /**\n * Cancel a quoted (unconfirmed) transaction.\n */\n async cancel(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.put<Transaction>(`/api/v2/transaction/${txnId}/cancel`);\n }\n\n /**\n * Wait for a transaction to reach a final state. Polls at the given interval.\n *\n * @param txnId Transaction ID\n * @param options.intervalMs Polling interval in ms (default: 3000)\n * @param options.timeoutMs Max wait time in ms (default: 300000 = 5 min)\n * @param options.onStateChange Callback fired on each state change\n * @returns The transaction in a final state\n *\n * @example\n * const txn = await neutron.transactions.waitForCompletion(txnId, {\n * onStateChange: (state) => console.log(\"State:\", state),\n * });\n */\n async waitForCompletion(\n txnId: string,\n options?: {\n intervalMs?: number;\n timeoutMs?: number;\n onStateChange?: (state: string, txn: Transaction) => void;\n }\n ): Promise<Transaction> {\n const FINAL_STATES = [\"completed\", \"failed\", \"expired\", \"rejected\", \"error\", \"usercanceled\"];\n const interval = options?.intervalMs ?? 3000;\n const timeout = options?.timeoutMs ?? 300_000;\n const start = Date.now();\n let lastState = \"\";\n\n while (Date.now() - start < timeout) {\n const txn = await this.get(txnId);\n\n if (txn.txnState !== lastState) {\n lastState = txn.txnState;\n options?.onStateChange?.(txn.txnState, txn);\n }\n\n if (FINAL_STATES.includes(txn.txnState)) {\n return txn;\n }\n\n await new Promise((r) => setTimeout(r, interval));\n }\n\n throw new Error(`Transaction ${txnId} did not complete within ${timeout}ms`);\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type {\n CreateInvoiceParams,\n LightningInvoice,\n DecodedInvoice,\n LightningAddressInfo,\n LnurlInfo,\n Transaction,\n} from \"../types.js\";\nimport { NeutronValidationError } from \"../errors.js\";\n\nexport class LightningResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Create a Lightning invoice to receive Bitcoin. Auto-confirms — ready to pay immediately.\n *\n * @example\n * const invoice = await neutron.lightning.createInvoice({ amountSats: 10000 });\n * console.log(invoice.invoice); // \"lnbc100u1p...\"\n * console.log(invoice.qrPageUrl); // hosted QR code page\n *\n * @example\n * const invoice = await neutron.lightning.createInvoice({\n * amountBtc: 0.001,\n * memo: \"Order #1234\",\n * extRefId: \"order-1234\",\n * });\n */\n async createInvoice(params: CreateInvoiceParams): Promise<LightningInvoice> {\n let btcAmount: number;\n\n if (params.amountSats !== undefined && params.amountBtc !== undefined) {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc, not both.\");\n }\n if (params.amountSats !== undefined) {\n if (params.amountSats <= 0) throw new NeutronValidationError(\"amountSats must be positive.\");\n btcAmount = params.amountSats / 100_000_000;\n } else if (params.amountBtc !== undefined) {\n if (params.amountBtc <= 0) throw new NeutronValidationError(\"amountBtc must be positive.\");\n btcAmount = params.amountBtc;\n } else {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc.\");\n }\n\n // Create\n const txn = await this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: {} },\n destReq: {\n ccy: \"BTC\",\n method: \"neutronpay\",\n amtRequested: btcAmount,\n reqDetails: {},\n },\n });\n\n // Auto-confirm\n const confirmed = await this.client.put<Transaction>(\n `/api/v2/transaction/${txn.txnId}/confirm`\n );\n\n return {\n txnId: confirmed.txnId,\n invoice: confirmed.sourceReq?.reqDetails?.paymentRequest ?? \"\",\n qrPageUrl: confirmed.sourceReq?.reqDetails?.invoicePageUrl,\n amountBtc: btcAmount,\n amountSats: Math.round(btcAmount * 100_000_000),\n status: confirmed.txnState,\n };\n }\n\n /**\n * Pay a Lightning invoice (BOLT11).\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to send.\n *\n * @example\n * const txn = await neutron.lightning.payInvoice(\"lnbc100u1p...\");\n * // Review fees: txn.sourceReq.neutronpayFees\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payInvoice(invoice: string, extRefId?: string): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId,\n sourceReq: { ccy: \"BTC\", method: \"neutronpay\" },\n destReq: {\n ccy: \"BTC\",\n method: \"lightning\",\n reqDetails: { paymentRequest: invoice },\n },\n });\n }\n\n /**\n * Send to a Lightning Address (user@domain.com).\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to send.\n *\n * @example\n * const txn = await neutron.lightning.payAddress(\"alice@getalby.com\", { amountSats: 5000 });\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payAddress(\n address: string,\n params: { amountSats?: number; amountBtc?: number; extRefId?: string }\n ): Promise<Transaction> {\n let btcAmount: number;\n if (params.amountSats !== undefined) {\n btcAmount = params.amountSats / 100_000_000;\n } else if (params.amountBtc !== undefined) {\n btcAmount = params.amountBtc;\n } else {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc.\");\n }\n\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: btcAmount },\n destReq: {\n ccy: \"BTC\",\n method: \"lnurl\",\n reqDetails: { lnurl: address },\n },\n });\n }\n\n /**\n * Decode a BOLT11 invoice to inspect it before paying.\n * Returns amount, expiry, destination node, description, and payment status.\n */\n async decodeInvoice(invoice: string): Promise<DecodedInvoice> {\n return this.client.get<DecodedInvoice>(\n `/api/v2/lightning/invoice?invoice=${encodeURIComponent(invoice)}`\n );\n }\n\n /**\n * Resolve a Lightning Address (user@domain.com) to check if it exists\n * and get min/max sendable amounts.\n *\n * @param amountMsat Optional: get a specific invoice for this amount (in millisatoshis)\n */\n async resolveAddress(address: string, amountMsat?: number): Promise<LightningAddressInfo> {\n let path = `/api/v2/lightning/resolve-ln-address?lnAddress=${encodeURIComponent(address)}`;\n if (amountMsat !== undefined) path += `&amount=${amountMsat}`;\n return this.client.get<LightningAddressInfo>(path);\n }\n\n /**\n * Resolve an LNURL string to see its type (pay/withdraw/channel) and parameters.\n */\n async resolveLnurl(lnurl: string): Promise<LnurlInfo> {\n return this.client.get<LnurlInfo>(\n `/api/v2/lightning/resolve-lnurl?lnurl=${encodeURIComponent(lnurl)}`\n );\n }\n}\n","import crypto from \"crypto\";\nimport type { HttpClient } from \"../client.js\";\nimport type { Webhook, CreateWebhookParams, UpdateWebhookParams } from \"../types.js\";\nimport { NeutronValidationError } from \"../errors.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class WebhooksResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Register a webhook to receive transaction state change notifications.\n *\n * @example\n * const webhook = await neutron.webhooks.create({\n * callback: \"https://myapp.com/webhooks/neutron\",\n * secret: \"my-webhook-secret\",\n * });\n */\n async create(params: CreateWebhookParams): Promise<Webhook> {\n return this.client.post<Webhook>(`/api/v2/webhook`, params);\n }\n\n /**\n * List all registered webhooks.\n */\n async list(): Promise<Webhook[]> {\n const res = await this.client.get(`/api/v2/webhook`);\n return res.data ?? res;\n }\n\n /**\n * Update a webhook's callback URL or secret.\n */\n async update(webhookId: string, params: UpdateWebhookParams): Promise<Webhook> {\n sanitizePathParam(webhookId, \"webhookId\");\n return this.client.put<Webhook>(`/api/v2/webhook/${webhookId}`, params);\n }\n\n /**\n * Delete a webhook.\n */\n async delete(webhookId: string): Promise<void> {\n sanitizePathParam(webhookId, \"webhookId\");\n await this.client.del(`/api/v2/webhook/${webhookId}`);\n }\n\n /**\n * Verify a webhook signature from an incoming request.\n * Throws if the signature is invalid.\n *\n * @param body The raw request body (string or Buffer)\n * @param signature The `X-Neutronpay-Signature` header value\n * @param secret Your webhook secret\n * @returns The parsed event payload\n *\n * @example\n * // Express\n * app.post(\"/webhooks/neutron\", express.raw({ type: \"application/json\" }), (req, res) => {\n * try {\n * const event = Neutron.webhooks.verifySignature(\n * req.body,\n * req.headers[\"x-neutronpay-signature\"],\n * \"my-webhook-secret\"\n * );\n * // event is verified and safe to use\n * if (event.txnState === \"completed\") fulfillOrder(event.extRefId);\n * } catch (err) {\n * return res.status(401).send(\"Invalid signature\");\n * }\n * res.status(200).send(\"OK\");\n * });\n */\n static verifySignature(\n body: string | Buffer,\n signature: string | undefined | null,\n secret: string\n ): any {\n if (!signature) {\n throw new NeutronValidationError(\"Missing webhook signature header (X-Neutronpay-Signature)\");\n }\n if (!secret) {\n throw new NeutronValidationError(\"Webhook secret is required for verification\");\n }\n\n const bodyStr = typeof body === \"string\" ? body : body.toString(\"utf8\");\n\n const expected = crypto\n .createHmac(\"sha256\", secret)\n .update(bodyStr)\n .digest(\"hex\");\n\n const sigBuf = Buffer.from(signature);\n const expBuf = Buffer.from(expected);\n const isValid = sigBuf.length === expBuf.length && crypto.timingSafeEqual(sigBuf, expBuf);\n\n if (!isValid) {\n throw new NeutronValidationError(\"Invalid webhook signature\");\n }\n\n return JSON.parse(bodyStr);\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { ExchangeRates } from \"../types.js\";\n\nexport class RatesResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Get current BTC exchange rates against all supported currencies.\n *\n * @example\n * const rates = await neutron.rates.get();\n * console.log(rates); // { BTCUSD: 97500, BTCVND: 2437500000, ... }\n */\n async get(): Promise<ExchangeRates> {\n const res = await this.client.get(`/api/v2/rate`);\n return res.data ?? res;\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { FiatInstitution, Transaction, SourceOfFunds } from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport interface FiatPayoutParams {\n /** Source currency (e.g. \"BTC\") */\n sourceCcy: string;\n /** Amount from source (in BTC for Bitcoin) */\n sourceAmount: number;\n /** Destination fiat currency (e.g. \"VND\") */\n destCcy: string;\n /** Payment method (e.g. \"vnd-instant\") */\n destMethod: string;\n /** Bank account number */\n bankAcctNum: string;\n /** Bank code from `neutron.fiat.institutions()` */\n institutionCode: string;\n /** Recipient legal full name */\n recipientName: string;\n /** Recipient country code (e.g. \"VN\") */\n countryCode: string;\n /** \"individual\" or \"business\" (default: \"individual\") */\n kycType?: \"individual\" | \"business\";\n /** Source of funds declaration */\n sourceOfFunds?: SourceOfFunds;\n /** Your reference ID */\n extRefId?: string;\n}\n\nexport class FiatResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * List banks and financial institutions for a country.\n * Returns institution codes needed for fiat payouts.\n *\n * @example\n * const banks = await neutron.fiat.institutions(\"VN\");\n * // [{ code: \"970422\", name: \"MB Bank\" }, ...]\n */\n async institutions(countryCode: string): Promise<FiatInstitution[]> {\n sanitizePathParam(countryCode, \"countryCode\");\n const res = await this.client.get(\n `/api/v2/reference/fiat-institution/by-country/${countryCode}`\n );\n return res.data ?? res;\n }\n\n /**\n * Create a fiat payout transaction. Handles KYC and source of funds automatically.\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to execute.\n *\n * @example\n * const txn = await neutron.fiat.payout({\n * sourceCcy: \"BTC\",\n * sourceAmount: 0.001,\n * destCcy: \"VND\",\n * destMethod: \"vnd-instant\",\n * bankAcctNum: \"0123456789\",\n * institutionCode: \"970422\",\n * recipientName: \"LE VAN A\",\n * countryCode: \"VN\",\n * });\n * // Review rate: txn.fxRate\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payout(params: FiatPayoutParams): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: {\n ccy: params.sourceCcy,\n method: \"neutronpay\",\n amtRequested: params.sourceAmount,\n reqDetails: {},\n },\n destReq: {\n ccy: params.destCcy,\n method: params.destMethod,\n reqDetails: {\n bankAcctNum: params.bankAcctNum,\n institutionCode: params.institutionCode,\n },\n kyc: {\n type: params.kycType || \"individual\",\n details: {\n legalFullName: params.recipientName,\n countryCode: params.countryCode,\n },\n },\n },\n sourceOfFunds: params.sourceOfFunds ?? {\n purpose: 1,\n source: 5,\n relationship: 3,\n },\n });\n }\n}\n","// ── Satoshi / BTC conversion ────────────────────────────────\n\nconst SATS_PER_BTC = 100_000_000;\n\n/**\n * Convert satoshis to BTC.\n * @example satsToBtc(10000) // 0.0001\n */\nexport function satsToBtc(sats: number): number {\n return sats / SATS_PER_BTC;\n}\n\n/**\n * Convert BTC to satoshis.\n * @example btcToSats(0.0001) // 10000\n */\nexport function btcToSats(btc: number): number {\n return Math.round(btc * SATS_PER_BTC);\n}\n\n/**\n * Format a satoshi amount as a human-readable string.\n * @example formatSats(1500000) // \"1,500,000 sats\"\n * @example formatSats(100) // \"100 sats\"\n */\nexport function formatSats(sats: number): string {\n return `${sats.toLocaleString(\"en-US\")} sats`;\n}\n\n/**\n * Format a BTC amount with appropriate precision.\n * @example formatBtc(0.00015) // \"0.00015000 BTC\"\n */\nexport function formatBtc(btc: number): string {\n return `${btc.toFixed(8)} BTC`;\n}\n\n// ── Constants ───────────────────────────────────────────────\n\n/** Supported currencies */\nexport const Currency = {\n BTC: \"BTC\",\n USDT: \"USDT\",\n VND: \"VND\",\n USD: \"USD\",\n CAD: \"CAD\",\n NGN: \"NGN\",\n KES: \"KES\",\n GHS: \"GHS\",\n} as const;\n\nexport type Currency = (typeof Currency)[keyof typeof Currency];\n\n/** Payment methods for sourceReq/destReq */\nexport const PaymentMethod = {\n /** Internal Neutron wallet */\n NEUTRON: \"neutronpay\",\n /** Lightning Network (BOLT11 invoices) */\n LIGHTNING: \"lightning\",\n /** Lightning Address / LNURL */\n LNURL: \"lnurl\",\n /** Bitcoin on-chain */\n ON_CHAIN: \"on-chain\",\n /** USDT on TRON (TRC-20) */\n TRON: \"tron\",\n /** USDT on Ethereum (ERC-20) */\n ETH: \"eth\",\n /** Vietnamese Dong instant bank transfer */\n VND_INSTANT: \"vnd-instant\",\n} as const;\n\nexport type PaymentMethodType = (typeof PaymentMethod)[keyof typeof PaymentMethod];\n\n/** Transaction final states (terminal — won't change) */\nexport const FinalStates = [\n \"completed\",\n \"expired\",\n \"rejected\",\n \"error\",\n \"usercanceled\",\n] as const;\n\n/** All transaction states */\nexport const TransactionStates = {\n QUOTED: \"quoted\",\n USER_CONFIRMED: \"userconfirmed\",\n SRC_CREATED: \"srccreated\",\n SRC_SENT: \"srcsent\",\n SRC_INTENT: \"srcintent\",\n SRC_PEND_CONFIRM: \"srcpendconfirmfill\",\n SRC_CONFIRMED: \"srcconfirmfilled\",\n DEST_PEND_SENT: \"destpendsent\",\n DEST_SENT: \"destsent\",\n COMPLETED: \"completed\",\n EXPIRED: \"expired\",\n REJECTED: \"rejected\",\n ERROR: \"error\",\n USER_CANCELED: \"usercanceled\",\n} as const;\n\n/** USDT blockchain options */\nexport const Chain = {\n TRON: \"TRON\",\n ETH: \"ETH\",\n} as const;\n","import { HttpClient } from \"./client.js\";\nimport { AccountResource } from \"./resources/account.js\";\nimport { TransactionsResource } from \"./resources/transactions.js\";\nimport { LightningResource } from \"./resources/lightning.js\";\nimport { WebhooksResource } from \"./resources/webhooks.js\";\nimport { RatesResource } from \"./resources/rates.js\";\nimport { FiatResource } from \"./resources/fiat.js\";\nimport type { NeutronConfig } from \"./types.js\";\n\n/**\n * Neutron SDK — Bitcoin Lightning, stablecoins, and fiat payments.\n *\n * @example\n * import { Neutron } from \"neutron-sdk\";\n *\n * const neutron = new Neutron({\n * apiKey: process.env.NEUTRON_API_KEY!,\n * apiSecret: process.env.NEUTRON_API_SECRET!,\n * });\n *\n * // Check balances\n * const wallets = await neutron.account.wallets();\n *\n * // Create a Lightning invoice\n * const invoice = await neutron.lightning.createInvoice({ amountSats: 10000 });\n *\n * // Send to a Lightning Address\n * const txn = await neutron.lightning.payAddress(\"alice@getalby.com\", { amountSats: 5000 });\n * await neutron.transactions.confirm(txn.txnId);\n */\nexport class Neutron {\n /** Account info, wallets, and deposit addresses */\n readonly account: AccountResource;\n /** Create, confirm, list, and track transactions */\n readonly transactions: TransactionsResource;\n /** Lightning invoices, payments, and utilities */\n readonly lightning: LightningResource;\n /** Webhook management */\n readonly webhooks: WebhooksResource;\n /** BTC exchange rates */\n readonly rates: RatesResource;\n /** Fiat payouts and bank lookups */\n readonly fiat: FiatResource;\n\n private readonly client: HttpClient;\n\n constructor(config: NeutronConfig) {\n this.client = new HttpClient(config);\n this.account = new AccountResource(this.client);\n this.transactions = new TransactionsResource(this.client);\n this.lightning = new LightningResource(this.client);\n this.webhooks = new WebhooksResource(this.client);\n this.rates = new RatesResource(this.client);\n this.fiat = new FiatResource(this.client);\n }\n\n /**\n * Explicitly authenticate and verify credentials.\n * Usually not needed — the SDK auto-authenticates on first request.\n */\n async authenticate() {\n return this.client.authenticate();\n }\n\n /**\n * Verify a webhook signature. Static method — no client instance needed.\n *\n * @example\n * const event = Neutron.verifyWebhook(req.body, req.headers[\"x-neutronpay-signature\"], secret);\n */\n static verifyWebhook(body: string | Buffer, signature: string | undefined | null, secret: string) {\n return WebhooksResource.verifySignature(body, signature, secret);\n }\n}\n\n// ── Exports ─────────────────────────────────────────────────\n\nexport { HttpClient } from \"./client.js\";\nexport { AccountResource } from \"./resources/account.js\";\nexport { TransactionsResource } from \"./resources/transactions.js\";\nexport { LightningResource } from \"./resources/lightning.js\";\nexport { WebhooksResource } from \"./resources/webhooks.js\";\nexport { RatesResource } from \"./resources/rates.js\";\nexport { FiatResource } from \"./resources/fiat.js\";\nexport type { FiatPayoutParams } from \"./resources/fiat.js\";\n\nexport { sanitizePathParam } from \"./sanitize.js\";\n\nexport {\n NeutronError,\n NeutronApiError,\n NeutronAuthError,\n NeutronTimeoutError,\n NeutronValidationError,\n} from \"./errors.js\";\n\nexport {\n satsToBtc,\n btcToSats,\n formatSats,\n formatBtc,\n Currency,\n PaymentMethod,\n TransactionStates,\n FinalStates,\n Chain,\n} from \"./utils.js\";\n\nexport type {\n Currency as CurrencyType,\n PaymentMethodType,\n} from \"./utils.js\";\n\nexport type {\n NeutronConfig,\n AuthResponse,\n Account,\n Wallet,\n Transaction,\n TransactionState,\n TransactionSide,\n PaymentMethod as PaymentMethodString,\n CreateTransactionRequest,\n ListTransactionsParams,\n CreateInvoiceParams,\n LightningInvoice,\n DecodedInvoice,\n LightningAddressInfo,\n LnurlInfo,\n BtcAddress,\n UsdtAddress,\n Webhook,\n CreateWebhookParams,\n UpdateWebhookParams,\n ExchangeRates,\n FiatInstitution,\n KycInfo,\n SourceOfFunds,\n ApiResponse,\n} from \"./types.js\";\n"],"mappings":";AAAA,OAAO,YAAY;;;ACGZ,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,kBAAN,cAA8B,aAAa;AAAA;AAAA,EAEvC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YAAY,QAAgB,MAAW;AACrC,UAAM,UAAU,MAAM,SAAS,MAAM,WAAW,aAAa,MAAM;AACnE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO,MAAM;AAClB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,gBAAyB;AAC3B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,IAAI,cAAuB;AACzB,WAAO,KAAK,WAAW,OAAO,KAAK,WAAW;AAAA,EAChD;AAAA;AAAA,EAGA,IAAI,cAAuB;AACzB,WAAO,KAAK,WAAW,OAAO,KAAK,UAAU;AAAA,EAC/C;AACF;AAKO,IAAM,mBAAN,cAA+B,aAAa;AAAA,EACjD,YAAY,UAAkB,yDAAyD;AACrF,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,sBAAN,cAAkC,aAAa;AAAA,EACpD,YAAY,WAAmB;AAC7B,UAAM,2BAA2B,SAAS,IAAI;AAC9C,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,yBAAN,cAAqC,aAAa;AAAA,EACvD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;ADlEA,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AACxB,IAAM,sBAAsB;AAC5B,IAAM,0BAA0B;AAEzB,IAAM,aAAN,MAAiB;AAAA,EACL;AAAA,EACA;AAAA,EACR;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA,EAET,cAA6B;AAAA,EAC7B,YAA2B;AAAA,EAC3B,cAAsB;AAAA,EAE9B,YAAY,QAAuB;AACjC,QAAI,CAAC,OAAO,OAAQ,OAAM,IAAI,iBAAiB,oBAAoB;AACnE,QAAI,CAAC,OAAO,UAAW,OAAM,IAAI,iBAAiB,uBAAuB;AAEzE,SAAK,SAAS,OAAO;AACrB,SAAK,YAAY,OAAO;AACxB,SAAK,WAAW,OAAO,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACtE,SAAK,UAAU,OAAO,WAAW;AACjC,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,QAAQ,OAAO,SAAS;AAAA,EAC/B;AAAA,EAEQ,IAAI,SAAiB,MAAkB;AAC7C,QAAI,CAAC,KAAK,MAAO;AACjB,UAAM,MAAK,oBAAI,KAAK,GAAE,YAAY;AAClC,UAAM,QAAQ,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK;AAClD,YAAQ,MAAM,gBAAgB,EAAE,KAAK,OAAO,GAAG,KAAK,EAAE;AAAA,EACxD;AAAA;AAAA,EAIQ,kBAAkB,SAAyB;AACjD,UAAM,eAAe,GAAG,KAAK,MAAM,YAAY,OAAO;AACtD,WAAO,OACJ,WAAW,UAAU,KAAK,SAAS,EACnC,OAAO,YAAY,EACnB,OAAO,KAAK;AAAA,EACjB;AAAA,EAEA,IAAY,eAAwB;AAClC,WAAO,CAAC,EACN,KAAK,eACL,KAAK,aACL,KAAK,IAAI,IAAI,KAAK,cAAc;AAAA,EAEpC;AAAA,EAEA,MAAM,eAAsC;AAC1C,UAAM,UAAU,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAC/C,UAAM,YAAY,KAAK,kBAAkB,OAAO;AAEhD,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,GAAG,KAAK,OAAO;AAAA,MACf;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,aAAa,KAAK;AAAA,UAClB,mBAAmB;AAAA,QACrB;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACpD,YAAM,IAAI;AAAA,QACR,KAAK,SAAS,KAAK,WAAW,0BAA0B,SAAS,MAAM;AAAA,MACzE;AAAA,IACF;AAEA,UAAM,MAAO,MAAM,SAAS,KAAK;AAEjC,UAAM,SAAuB,IAAI,QAAQ;AACzC,SAAK,YAAY,OAAO;AACxB,SAAK,cAAc,OAAO;AAC1B,SAAK,cAAc,OAAO,OAAO,cAAc,WAC3C,OAAO,YACP,IAAI,KAAK,OAAO,SAAS,EAAE,QAAQ;AAEvC,WAAO;AACP,SAAK,IAAI,iBAAiB,EAAE,WAAW,KAAK,UAAU,CAAC;AAAA,EACzD;AAAA,EAEA,MAAc,aAA4B;AACxC,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,KAAK,aAAa;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,eAAuB;AACrB,QAAI,CAAC,KAAK,WAAW;AACnB,YAAM,IAAI,iBAAiB,sEAAsE;AAAA,IACnG;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,4BAA6C;AACjD,UAAM,KAAK,WAAW;AACtB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIA,MAAc,SAAS,KAAa,MAAsC;AACxE,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,OAAO;AAE/D,QAAI;AACF,aAAO,MAAM,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,IAChE,SAAS,KAAU;AACjB,UAAI,IAAI,SAAS,cAAc;AAC7B,cAAM,IAAI,oBAAoB,KAAK,OAAO;AAAA,MAC5C;AACA,YAAM;AAAA,IACR,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,QAAiB,QAAgB,MAAc,MAAwB;AAC3E,UAAM,KAAK,WAAW;AAEtB,QAAI;AAEJ,aAAS,UAAU,GAAG,WAAW,KAAK,YAAY,WAAW;AAC3D,UAAI,UAAU,GAAG;AAEf,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,KAAK,IAAI,GAAG,UAAU,CAAC,IAAI,GAAI,CAAC;AAGvE,YAAI,CAAC,KAAK,aAAc,OAAM,KAAK,aAAa;AAAA,MAClD;AAEA,YAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI;AAClC,WAAK,IAAI,GAAG,MAAM,IAAI,IAAI,EAAE;AAC5B,YAAM,UAAkC;AAAA,QACtC,eAAe,UAAU,KAAK,WAAW;AAAA,MAC3C;AACA,UAAI,KAAM,SAAQ,cAAc,IAAI;AAEpC,YAAM,WAAW,MAAM,KAAK,SAAS,KAAK;AAAA,QACxC;AAAA,QACA;AAAA,QACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACtC,CAAC;AAED,UAAI,SAAS,IAAI;AACf,eAAQ,MAAM,SAAS,KAAK;AAAA,MAC9B;AAEA,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,YAAM,WAAW,IAAI,gBAAgB,SAAS,QAAQ,SAAS;AAG/D,UAAI,SAAS,WAAW,OAAO,UAAU,KAAK,YAAY;AACxD,aAAK,cAAc;AACnB,oBAAY;AACZ;AAAA,MACF;AAGA,UAAI,SAAS,eAAe,UAAU,KAAK,YAAY;AACrD,oBAAY;AACZ;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAEA,UAAM;AAAA,EACR;AAAA,EAEA,MAAM,IAAa,MAA0B;AAC3C,WAAO,KAAK,QAAW,OAAO,IAAI;AAAA,EACpC;AAAA,EAEA,MAAM,KAAc,MAAc,MAAwB;AACxD,WAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;AAAA,EAC3C;AAAA,EAEA,MAAM,IAAa,MAAc,MAAwB;AACvD,WAAO,KAAK,QAAW,OAAO,MAAM,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAM,IAAa,MAA0B;AAC3C,WAAO,KAAK,QAAW,UAAU,IAAI;AAAA,EACvC;AACF;;;AErMO,SAAS,kBAAkB,OAAe,MAAsB;AACrE,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,UAAM,IAAI,uBAAuB,GAAG,IAAI,8CAA8C;AAAA,EACxF;AAGA,QAAM,YAAY,MAAM,QAAQ,qBAAqB,EAAE;AAEvD,MAAI,cAAc,OAAO;AACvB,UAAM,IAAI;AAAA,MACR,GAAG,IAAI;AAAA,IACT;AAAA,EACF;AAEA,MAAI,UAAU,SAAS,IAAI,GAAG;AAC5B,UAAM,IAAI,uBAAuB,GAAG,IAAI,2CAA2C;AAAA,EACrF;AAEA,SAAO;AACT;;;ACrBO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA,EAKlD,MAAM,MAAwB;AAC5B,UAAM,YAAY,MAAM,KAAK,OAAO,0BAA0B;AAC9D,UAAM,MAAM,MAAM,KAAK,OAAO,IAAI,mBAAmB,SAAS,EAAE;AAChE,WAAQ,IAAI,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAA6B;AACjC,UAAM,YAAY,MAAM,KAAK,OAAO,0BAA0B;AAC9D,UAAM,MAAM,MAAM,KAAK,OAAO,IAAI,mBAAmB,SAAS,UAAU;AACxE,WAAO,IAAI,QAAQ;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,UAAmC;AAC9C,sBAAkB,UAAU,UAAU;AACtC,UAAM,YAAY,MAAM,KAAK,OAAO,0BAA0B;AAC9D,UAAM,MAAM,MAAM,KAAK,OAAO,IAAI,mBAAmB,SAAS,WAAW,QAAQ,EAAE;AACnF,WAAQ,IAAI,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA2C;AAC/C,UAAM,MAAM,MAAM,KAAK,OAAO,IAAI,iCAAiC;AACnE,UAAM,OAAO,KAAK,QAAQ;AAC1B,WAAO,EAAE,SAAS,KAAK,qBAAqB;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,QAAwB,QAAqD;AAC7F,UAAM,MAAM,MAAM,KAAK,OAAO;AAAA,MAC5B,qEAAqE,KAAK;AAAA,IAC5E;AACA,UAAM,OAAO,KAAK,QAAQ;AAC1B,WAAO;AAAA,MACL,SAAS,KAAK,kCAAkC,KAAK;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;;;AClDO,IAAM,uBAAN,MAA2B;AAAA,EAChC,YAA6B,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BlD,MAAM,OAAO,QAAwD;AACnE,WAAO,KAAK,OAAO,KAAkB,uBAAuB,MAAM;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,OAAqC;AACjD,sBAAkB,OAAO,OAAO;AAChC,WAAO,KAAK,OAAO,IAAiB,uBAAuB,KAAK,UAAU;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,OAAqC;AAC7C,sBAAkB,OAAO,OAAO;AAChC,WAAO,KAAK,OAAO,IAAiB,uBAAuB,KAAK,EAAE;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,QAAyD;AAClE,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,QAAQ;AACV,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,YAAI,MAAM,UAAa,MAAM,KAAM,IAAG,OAAO,GAAG,OAAO,CAAC,CAAC;AAAA,MAC3D;AAAA,IACF;AACA,UAAM,QAAQ,GAAG,SAAS;AAC1B,UAAM,MAAM,MAAM,KAAK,OAAO,IAAI,sBAAsB,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE;AAClF,WAAO,IAAI,QAAQ;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,OAAqC;AAChD,sBAAkB,OAAO,OAAO;AAChC,WAAO,KAAK,OAAO,IAAiB,uBAAuB,KAAK,SAAS;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,kBACJ,OACA,SAKsB;AACtB,UAAM,eAAe,CAAC,aAAa,UAAU,WAAW,YAAY,SAAS,cAAc;AAC3F,UAAM,WAAW,SAAS,cAAc;AACxC,UAAM,UAAU,SAAS,aAAa;AACtC,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI,YAAY;AAEhB,WAAO,KAAK,IAAI,IAAI,QAAQ,SAAS;AACnC,YAAM,MAAM,MAAM,KAAK,IAAI,KAAK;AAEhC,UAAI,IAAI,aAAa,WAAW;AAC9B,oBAAY,IAAI;AAChB,iBAAS,gBAAgB,IAAI,UAAU,GAAG;AAAA,MAC5C;AAEA,UAAI,aAAa,SAAS,IAAI,QAAQ,GAAG;AACvC,eAAO;AAAA,MACT;AAEA,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAAA,IAClD;AAEA,UAAM,IAAI,MAAM,eAAe,KAAK,4BAA4B,OAAO,IAAI;AAAA,EAC7E;AACF;;;ACpHO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBlD,MAAM,cAAc,QAAwD;AAC1E,QAAI;AAEJ,QAAI,OAAO,eAAe,UAAa,OAAO,cAAc,QAAW;AACrE,YAAM,IAAI,uBAAuB,mDAAmD;AAAA,IACtF;AACA,QAAI,OAAO,eAAe,QAAW;AACnC,UAAI,OAAO,cAAc,EAAG,OAAM,IAAI,uBAAuB,8BAA8B;AAC3F,kBAAY,OAAO,aAAa;AAAA,IAClC,WAAW,OAAO,cAAc,QAAW;AACzC,UAAI,OAAO,aAAa,EAAG,OAAM,IAAI,uBAAuB,6BAA6B;AACzF,kBAAY,OAAO;AAAA,IACrB,OAAO;AACL,YAAM,IAAI,uBAAuB,yCAAyC;AAAA,IAC5E;AAGA,UAAM,MAAM,MAAM,KAAK,OAAO,KAAkB,uBAAuB;AAAA,MACrE,UAAU,OAAO;AAAA,MACjB,WAAW,EAAE,KAAK,OAAO,QAAQ,aAAa,YAAY,CAAC,EAAE;AAAA,MAC7D,SAAS;AAAA,QACP,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,YAAY,CAAC;AAAA,MACf;AAAA,IACF,CAAC;AAGD,UAAM,YAAY,MAAM,KAAK,OAAO;AAAA,MAClC,uBAAuB,IAAI,KAAK;AAAA,IAClC;AAEA,WAAO;AAAA,MACL,OAAO,UAAU;AAAA,MACjB,SAAS,UAAU,WAAW,YAAY,kBAAkB;AAAA,MAC5D,WAAW,UAAU,WAAW,YAAY;AAAA,MAC5C,WAAW;AAAA,MACX,YAAY,KAAK,MAAM,YAAY,GAAW;AAAA,MAC9C,QAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,WAAW,SAAiB,UAAyC;AACzE,WAAO,KAAK,OAAO,KAAkB,uBAAuB;AAAA,MAC1D;AAAA,MACA,WAAW,EAAE,KAAK,OAAO,QAAQ,aAAa;AAAA,MAC9C,SAAS;AAAA,QACP,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,YAAY,EAAE,gBAAgB,QAAQ;AAAA,MACxC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WACJ,SACA,QACsB;AACtB,QAAI;AACJ,QAAI,OAAO,eAAe,QAAW;AACnC,kBAAY,OAAO,aAAa;AAAA,IAClC,WAAW,OAAO,cAAc,QAAW;AACzC,kBAAY,OAAO;AAAA,IACrB,OAAO;AACL,YAAM,IAAI,uBAAuB,yCAAyC;AAAA,IAC5E;AAEA,WAAO,KAAK,OAAO,KAAkB,uBAAuB;AAAA,MAC1D,UAAU,OAAO;AAAA,MACjB,WAAW,EAAE,KAAK,OAAO,QAAQ,cAAc,cAAc,UAAU;AAAA,MACvE,SAAS;AAAA,QACP,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,YAAY,EAAE,OAAO,QAAQ;AAAA,MAC/B;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAc,SAA0C;AAC5D,WAAO,KAAK,OAAO;AAAA,MACjB,qCAAqC,mBAAmB,OAAO,CAAC;AAAA,IAClE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,SAAiB,YAAoD;AACxF,QAAI,OAAO,kDAAkD,mBAAmB,OAAO,CAAC;AACxF,QAAI,eAAe,OAAW,SAAQ,WAAW,UAAU;AAC3D,WAAO,KAAK,OAAO,IAA0B,IAAI;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,OAAmC;AACpD,WAAO,KAAK,OAAO;AAAA,MACjB,yCAAyC,mBAAmB,KAAK,CAAC;AAAA,IACpE;AAAA,EACF;AACF;;;AC3JA,OAAOA,aAAY;AAMZ,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWlD,MAAM,OAAO,QAA+C;AAC1D,WAAO,KAAK,OAAO,KAAc,mBAAmB,MAAM;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAA2B;AAC/B,UAAM,MAAM,MAAM,KAAK,OAAO,IAAI,iBAAiB;AACnD,WAAO,IAAI,QAAQ;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,WAAmB,QAA+C;AAC7E,sBAAkB,WAAW,WAAW;AACxC,WAAO,KAAK,OAAO,IAAa,mBAAmB,SAAS,IAAI,MAAM;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,WAAkC;AAC7C,sBAAkB,WAAW,WAAW;AACxC,UAAM,KAAK,OAAO,IAAI,mBAAmB,SAAS,EAAE;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BA,OAAO,gBACL,MACA,WACA,QACK;AACL,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,uBAAuB,2DAA2D;AAAA,IAC9F;AACA,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,uBAAuB,6CAA6C;AAAA,IAChF;AAEA,UAAM,UAAU,OAAO,SAAS,WAAW,OAAO,KAAK,SAAS,MAAM;AAEtE,UAAM,WAAWC,QACd,WAAW,UAAU,MAAM,EAC3B,OAAO,OAAO,EACd,OAAO,KAAK;AAEf,UAAM,SAAS,OAAO,KAAK,SAAS;AACpC,UAAM,SAAS,OAAO,KAAK,QAAQ;AACnC,UAAM,UAAU,OAAO,WAAW,OAAO,UAAUA,QAAO,gBAAgB,QAAQ,MAAM;AAExF,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,uBAAuB,2BAA2B;AAAA,IAC9D;AAEA,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B;AACF;;;AClGO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlD,MAAM,MAA8B;AAClC,UAAM,MAAM,MAAM,KAAK,OAAO,IAAI,cAAc;AAChD,WAAO,IAAI,QAAQ;AAAA,EACrB;AACF;;;ACYO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUlD,MAAM,aAAa,aAAiD;AAClE,sBAAkB,aAAa,aAAa;AAC5C,UAAM,MAAM,MAAM,KAAK,OAAO;AAAA,MAC5B,iDAAiD,WAAW;AAAA,IAC9D;AACA,WAAO,IAAI,QAAQ;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,OAAO,QAAgD;AAC3D,WAAO,KAAK,OAAO,KAAkB,uBAAuB;AAAA,MAC1D,UAAU,OAAO;AAAA,MACjB,WAAW;AAAA,QACT,KAAK,OAAO;AAAA,QACZ,QAAQ;AAAA,QACR,cAAc,OAAO;AAAA,QACrB,YAAY,CAAC;AAAA,MACf;AAAA,MACA,SAAS;AAAA,QACP,KAAK,OAAO;AAAA,QACZ,QAAQ,OAAO;AAAA,QACf,YAAY;AAAA,UACV,aAAa,OAAO;AAAA,UACpB,iBAAiB,OAAO;AAAA,QAC1B;AAAA,QACA,KAAK;AAAA,UACH,MAAM,OAAO,WAAW;AAAA,UACxB,SAAS;AAAA,YACP,eAAe,OAAO;AAAA,YACtB,aAAa,OAAO;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,MACA,eAAe,OAAO,iBAAiB;AAAA,QACrC,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC/FA,IAAM,eAAe;AAMd,SAAS,UAAU,MAAsB;AAC9C,SAAO,OAAO;AAChB;AAMO,SAAS,UAAU,KAAqB;AAC7C,SAAO,KAAK,MAAM,MAAM,YAAY;AACtC;AAOO,SAAS,WAAW,MAAsB;AAC/C,SAAO,GAAG,KAAK,eAAe,OAAO,CAAC;AACxC;AAMO,SAAS,UAAU,KAAqB;AAC7C,SAAO,GAAG,IAAI,QAAQ,CAAC,CAAC;AAC1B;AAKO,IAAM,WAAW;AAAA,EACtB,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAKO,IAAM,gBAAgB;AAAA;AAAA,EAE3B,SAAS;AAAA;AAAA,EAET,WAAW;AAAA;AAAA,EAEX,OAAO;AAAA;AAAA,EAEP,UAAU;AAAA;AAAA,EAEV,MAAM;AAAA;AAAA,EAEN,KAAK;AAAA;AAAA,EAEL,aAAa;AACf;AAKO,IAAM,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,oBAAoB;AAAA,EAC/B,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,eAAe;AACjB;AAGO,IAAM,QAAQ;AAAA,EACnB,MAAM;AAAA,EACN,KAAK;AACP;;;AC1EO,IAAM,UAAN,MAAc;AAAA;AAAA,EAEV;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAEQ;AAAA,EAEjB,YAAY,QAAuB;AACjC,SAAK,SAAS,IAAI,WAAW,MAAM;AACnC,SAAK,UAAU,IAAI,gBAAgB,KAAK,MAAM;AAC9C,SAAK,eAAe,IAAI,qBAAqB,KAAK,MAAM;AACxD,SAAK,YAAY,IAAI,kBAAkB,KAAK,MAAM;AAClD,SAAK,WAAW,IAAI,iBAAiB,KAAK,MAAM;AAChD,SAAK,QAAQ,IAAI,cAAc,KAAK,MAAM;AAC1C,SAAK,OAAO,IAAI,aAAa,KAAK,MAAM;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eAAe;AACnB,WAAO,KAAK,OAAO,aAAa;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,cAAc,MAAuB,WAAsC,QAAgB;AAChG,WAAO,iBAAiB,gBAAgB,MAAM,WAAW,MAAM;AAAA,EACjE;AACF;","names":["crypto","crypto"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/errors.ts","../src/sanitize.ts","../src/resources/account.ts","../src/resources/transactions.ts","../src/resources/lightning.ts","../src/resources/webhooks.ts","../src/resources/rates.ts","../src/resources/fiat.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import crypto from \"crypto\";\nimport type { NeutronConfig, AuthResponse } from \"./types.js\";\nimport {\n NeutronApiError,\n NeutronAuthError,\n NeutronTimeoutError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.neutron.me\";\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst TOKEN_REFRESH_BUFFER_MS = 60_000; // refresh 1 min before expiry\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly apiSecret: string;\n readonly baseUrl: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly debug: boolean;\n\n private accessToken: string | null = null;\n private accountId: string | null = null;\n private tokenExpiry: number = 0;\n\n constructor(config: NeutronConfig) {\n if (!config.apiKey) throw new NeutronAuthError(\"apiKey is required\");\n if (!config.apiSecret) throw new NeutronAuthError(\"apiSecret is required\");\n\n this.apiKey = config.apiKey;\n this.apiSecret = config.apiSecret;\n this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.debug = config.debug ?? false;\n }\n\n private log(message: string, data?: any): void {\n if (!this.debug) return;\n const ts = new Date().toISOString();\n const extra = data ? ` ${JSON.stringify(data)}` : \"\";\n console.error(`[neutron-sdk ${ts}] ${message}${extra}`);\n }\n\n // ── Auth ──────────────────────────────────────────────\n\n private generateSignature(payload: string): string {\n const stringToSign = `${this.apiKey}&payload=${payload}`;\n return crypto\n .createHmac(\"sha256\", this.apiSecret)\n .update(stringToSign)\n .digest(\"hex\");\n }\n\n private get isTokenValid(): boolean {\n return !!(\n this.accessToken &&\n this.accountId &&\n Date.now() < this.tokenExpiry - TOKEN_REFRESH_BUFFER_MS\n );\n }\n\n async authenticate(): Promise<AuthResponse> {\n const payload = JSON.stringify({ test: \"auth\" });\n const signature = this.generateSignature(payload);\n\n const response = await this.rawFetch(\n `${this.baseUrl}/api/v2/authentication/token-signature`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n \"X-Api-Signature\": signature,\n },\n body: payload,\n }\n );\n\n if (!response.ok) {\n const body = (await response.json().catch(() => ({}))) as Record<string, any>;\n throw new NeutronAuthError(\n body.error || body.message || `Authentication failed (${response.status})`\n );\n }\n\n const raw = (await response.json()) as any;\n // API wraps auth response in { data: { ... } }\n const result: AuthResponse = raw.data ?? raw;\n this.accountId = result.accountId;\n this.accessToken = result.accessToken;\n this.tokenExpiry = typeof result.expiredAt === \"number\"\n ? result.expiredAt\n : new Date(result.expiredAt).getTime();\n\n return result;\n this.log(\"Authenticated\", { accountId: this.accountId });\n }\n\n private async ensureAuth(): Promise<void> {\n if (!this.isTokenValid) {\n await this.authenticate();\n }\n }\n\n getAccountId(): string {\n if (!this.accountId) {\n throw new NeutronAuthError(\"Not authenticated. Call a method first or use neutron.account.get().\");\n }\n return this.accountId;\n }\n\n async ensureAuthAndGetAccountId(): Promise<string> {\n await this.ensureAuth();\n return this.accountId!;\n }\n\n // ── HTTP ──────────────────────────────────────────────\n\n private async rawFetch(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n throw new NeutronTimeoutError(this.timeout);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async request<T = any>(method: string, path: string, body?: any): Promise<T> {\n await this.ensureAuth();\n\n let lastError: any;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n // Exponential backoff: 1s, 2s, 4s...\n await new Promise((r) => setTimeout(r, Math.pow(2, attempt - 1) * 1000));\n\n // Re-auth if token might have expired during retries\n if (!this.isTokenValid) await this.authenticate();\n }\n\n const url = `${this.baseUrl}${path}`;\n this.log(`${method} ${path}`);\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.accessToken}`,\n };\n if (body) headers[\"Content-Type\"] = \"application/json\";\n\n const response = await this.rawFetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (response.ok) {\n return (await response.json()) as T;\n }\n\n const errorBody = await response.json().catch(() => ({}));\n const apiError = new NeutronApiError(response.status, errorBody);\n\n // Re-authenticate on 401 and retry\n if (response.status === 401 && attempt < this.maxRetries) {\n this.accessToken = null;\n lastError = apiError;\n continue;\n }\n\n // Retry on 5xx and 429\n if (apiError.isRetryable && attempt < this.maxRetries) {\n lastError = apiError;\n continue;\n }\n\n throw apiError;\n }\n\n throw lastError;\n }\n\n async get<T = any>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T = any>(path: string, body?: any): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T = any>(path: string, body?: any): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async del<T = any>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","/**\n * Base error for all Neutron SDK errors.\n */\nexport class NeutronError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NeutronError\";\n }\n}\n\n/**\n * Thrown when the API returns an error response (4xx/5xx).\n */\nexport class NeutronApiError extends NeutronError {\n /** HTTP status code */\n readonly status: number;\n /** Neutron error code (e.g. \"2005\") */\n readonly code: string | undefined;\n /** Raw error body from the API */\n readonly body: any;\n\n constructor(status: number, body: any) {\n const message = body?.error || body?.message || `API error ${status}`;\n super(message);\n this.name = \"NeutronApiError\";\n this.status = status;\n this.code = body?.code;\n this.body = body;\n }\n\n /** True if this is a rate limit error (429) */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n /** True if this is an auth error (401/403) */\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n /** True if retrying might help (5xx, 429) */\n get isRetryable(): boolean {\n return this.status === 429 || this.status >= 500;\n }\n}\n\n/**\n * Thrown when authentication fails.\n */\nexport class NeutronAuthError extends NeutronError {\n constructor(message: string = \"Authentication failed. Check your API key and secret.\") {\n super(message);\n this.name = \"NeutronAuthError\";\n }\n}\n\n/**\n * Thrown when a request times out.\n */\nexport class NeutronTimeoutError extends NeutronError {\n constructor(timeoutMs: number) {\n super(`Request timed out after ${timeoutMs}ms`);\n this.name = \"NeutronTimeoutError\";\n }\n}\n\n/**\n * Thrown for SDK usage errors (bad params, missing fields).\n */\nexport class NeutronValidationError extends NeutronError {\n constructor(message: string) {\n super(message);\n this.name = \"NeutronValidationError\";\n }\n}\n","import { NeutronValidationError } from \"./errors.js\";\n\n/**\n * Sanitize a path parameter to prevent path traversal and injection.\n * Only allows alphanumeric characters, hyphens, underscores, and dots.\n */\nexport function sanitizePathParam(value: string, name: string): string {\n if (!value || typeof value !== \"string\") {\n throw new NeutronValidationError(`${name} is required and must be a non-empty string.`);\n }\n\n // Strip any path traversal or special characters\n const sanitized = value.replace(/[^a-zA-Z0-9\\-_.]/g, \"\");\n\n if (sanitized !== value) {\n throw new NeutronValidationError(\n `${name} contains invalid characters. Only alphanumeric, hyphens, underscores, and dots are allowed.`\n );\n }\n\n if (sanitized.includes(\"..\")) {\n throw new NeutronValidationError(`${name} cannot contain path traversal sequences.`);\n }\n\n return sanitized;\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { Account, Wallet } from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class AccountResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Get account info: display name, status, country, timezone.\n */\n async get(): Promise<Account> {\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}`);\n return (res.data ?? res) as Account;\n }\n\n /**\n * List all wallets with balances (BTC, USDT, fiat).\n */\n async wallets(): Promise<Wallet[]> {\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}/wallet/`);\n return res.data ?? res;\n }\n\n /**\n * Get a specific wallet by ID.\n */\n async wallet(walletId: string): Promise<Wallet> {\n sanitizePathParam(walletId, \"walletId\");\n const accountId = await this.client.ensureAuthAndGetAccountId();\n const res = await this.client.get(`/api/v2/account/${accountId}/wallet/${walletId}`);\n return (res.data ?? res) as Wallet;\n }\n\n /**\n * Get your Bitcoin on-chain deposit address (static, reusable).\n */\n async btcAddress(): Promise<{ address: string }> {\n const raw = await this.client.get(`/api/v2/account/onchain-address`);\n const data = raw?.data ?? raw;\n return { address: data.staticOnchainAddress };\n }\n\n /**\n * Get your USDT deposit address.\n * @param chain \"TRON\" (default, recommended) or \"ETH\"\n */\n async usdtAddress(chain: \"TRON\" | \"ETH\" = \"TRON\"): Promise<{ address: string; chain: string }> {\n const raw = await this.client.get(\n `/api/v2/account/stablecoin-onchain-address?walletCcy=USDT&chainId=${chain}`\n );\n const data = raw?.data ?? raw;\n return {\n address: data.staticStablecoinOnchainAddress || data.staticOnchainAddress,\n chain,\n };\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type {\n Transaction,\n CreateTransactionRequest,\n ListTransactionsParams,\n} from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class TransactionsResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Create a transaction (returns a quote). Call `.confirm()` to execute.\n *\n * @example\n * // Lightning receive (create invoice)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: {} },\n * destReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: 0.0001, reqDetails: {} },\n * });\n *\n * @example\n * // Lightning send (pay invoice)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"neutronpay\" },\n * destReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: { paymentRequest: \"lnbc...\" } },\n * });\n *\n * @example\n * // Internal swap (BTC → USDT)\n * const txn = await neutron.transactions.create({\n * sourceReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: 0.001, reqDetails: {} },\n * destReq: { ccy: \"USDT\", method: \"neutronpay\", reqDetails: {} },\n * });\n */\n async create(params: CreateTransactionRequest): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, params);\n }\n\n /**\n * Confirm a quoted transaction to execute it.\n * After confirmation, Lightning invoices become payable and sends are dispatched.\n */\n async confirm(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.put<Transaction>(`/api/v2/transaction/${txnId}/confirm`);\n }\n\n /**\n * Get transaction status and details.\n */\n async get(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.get<Transaction>(`/api/v2/transaction/${txnId}`);\n }\n\n /**\n * List transactions with optional filters.\n *\n * @example\n * const completed = await neutron.transactions.list({ status: \"completed\", limit: 10 });\n */\n async list(params?: ListTransactionsParams): Promise<Transaction[]> {\n const qs = new URLSearchParams();\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null) qs.append(k, String(v));\n }\n }\n const query = qs.toString();\n const res = await this.client.get(`/api/v2/transaction${query ? `?${query}` : \"\"}`);\n return res.data ?? res;\n }\n\n /**\n * Cancel a quoted (unconfirmed) transaction.\n */\n async cancel(txnId: string): Promise<Transaction> {\n sanitizePathParam(txnId, \"txnId\");\n return this.client.put<Transaction>(`/api/v2/transaction/${txnId}/cancel`);\n }\n\n /**\n * Wait for a transaction to reach a final state. Polls at the given interval.\n *\n * @param txnId Transaction ID\n * @param options.intervalMs Polling interval in ms (default: 3000)\n * @param options.timeoutMs Max wait time in ms (default: 300000 = 5 min)\n * @param options.onStateChange Callback fired on each state change\n * @returns The transaction in a final state\n *\n * @example\n * const txn = await neutron.transactions.waitForCompletion(txnId, {\n * onStateChange: (state) => console.log(\"State:\", state),\n * });\n */\n async waitForCompletion(\n txnId: string,\n options?: {\n intervalMs?: number;\n timeoutMs?: number;\n onStateChange?: (state: string, txn: Transaction) => void;\n }\n ): Promise<Transaction> {\n const FINAL_STATES = [\"completed\", \"failed\", \"expired\", \"rejected\", \"error\", \"usercanceled\"];\n const interval = options?.intervalMs ?? 3000;\n const timeout = options?.timeoutMs ?? 300_000;\n const start = Date.now();\n let lastState = \"\";\n\n while (Date.now() - start < timeout) {\n const txn = await this.get(txnId);\n\n if (txn.txnState !== lastState) {\n lastState = txn.txnState;\n options?.onStateChange?.(txn.txnState, txn);\n }\n\n if (FINAL_STATES.includes(txn.txnState)) {\n return txn;\n }\n\n await new Promise((r) => setTimeout(r, interval));\n }\n\n throw new Error(`Transaction ${txnId} did not complete within ${timeout}ms`);\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type {\n CreateInvoiceParams,\n LightningInvoice,\n Transaction,\n} from \"../types.js\";\nimport { NeutronValidationError } from \"../errors.js\";\n\nexport class LightningResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Create a Lightning invoice to receive Bitcoin. Auto-confirms — ready to pay immediately.\n *\n * @example\n * const invoice = await neutron.lightning.createInvoice({ amountSats: 10000 });\n * console.log(invoice.invoice); // \"lnbc100u1p...\"\n * console.log(invoice.qrPageUrl); // hosted QR code page\n *\n * @example\n * const invoice = await neutron.lightning.createInvoice({\n * amountBtc: 0.001,\n * memo: \"Order #1234\",\n * extRefId: \"order-1234\",\n * });\n */\n async createInvoice(params: CreateInvoiceParams): Promise<LightningInvoice> {\n let btcAmount: number;\n\n if (params.amountSats !== undefined && params.amountBtc !== undefined) {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc, not both.\");\n }\n if (params.amountSats !== undefined) {\n if (params.amountSats <= 0) throw new NeutronValidationError(\"amountSats must be positive.\");\n btcAmount = params.amountSats / 100_000_000;\n } else if (params.amountBtc !== undefined) {\n if (params.amountBtc <= 0) throw new NeutronValidationError(\"amountBtc must be positive.\");\n btcAmount = params.amountBtc;\n } else {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc.\");\n }\n\n // Create\n const txn = await this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: { ccy: \"BTC\", method: \"lightning\", reqDetails: {} },\n destReq: {\n ccy: \"BTC\",\n method: \"neutronpay\",\n amtRequested: btcAmount,\n reqDetails: {},\n },\n });\n\n // Auto-confirm\n const confirmed = await this.client.put<Transaction>(\n `/api/v2/transaction/${txn.txnId}/confirm`\n );\n\n return {\n txnId: confirmed.txnId,\n invoice: confirmed.sourceReq?.reqDetails?.paymentRequest ?? \"\",\n qrPageUrl: confirmed.sourceReq?.reqDetails?.invoicePageUrl,\n amountBtc: btcAmount,\n amountSats: Math.round(btcAmount * 100_000_000),\n status: confirmed.txnState,\n };\n }\n\n /**\n * Pay a Lightning invoice (BOLT11).\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to send.\n *\n * @example\n * const txn = await neutron.lightning.payInvoice(\"lnbc100u1p...\");\n * // Review fees: txn.sourceReq.neutronpayFees\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payInvoice(invoice: string, extRefId?: string): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId,\n sourceReq: { ccy: \"BTC\", method: \"neutronpay\" },\n destReq: {\n ccy: \"BTC\",\n method: \"lightning\",\n reqDetails: { paymentRequest: invoice },\n },\n });\n }\n\n /**\n * Send to a Lightning Address (user@domain.com).\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to send.\n *\n * @example\n * const txn = await neutron.lightning.payAddress(\"alice@getalby.com\", { amountSats: 5000 });\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payAddress(\n address: string,\n params: { amountSats?: number; amountBtc?: number; extRefId?: string }\n ): Promise<Transaction> {\n let btcAmount: number;\n if (params.amountSats !== undefined) {\n btcAmount = params.amountSats / 100_000_000;\n } else if (params.amountBtc !== undefined) {\n btcAmount = params.amountBtc;\n } else {\n throw new NeutronValidationError(\"Provide either amountSats or amountBtc.\");\n }\n\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: { ccy: \"BTC\", method: \"neutronpay\", amtRequested: btcAmount },\n destReq: {\n ccy: \"BTC\",\n method: \"lnurl\",\n reqDetails: { lnurl: address },\n },\n });\n }\n\n}\n","import crypto from \"crypto\";\nimport type { HttpClient } from \"../client.js\";\nimport type { Webhook, CreateWebhookParams, UpdateWebhookParams } from \"../types.js\";\nimport { NeutronValidationError } from \"../errors.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport class WebhooksResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Register a webhook to receive transaction state change notifications.\n *\n * @example\n * const webhook = await neutron.webhooks.create({\n * callback: \"https://myapp.com/webhooks/neutron\",\n * secret: \"my-webhook-secret\",\n * });\n */\n async create(params: CreateWebhookParams): Promise<Webhook> {\n return this.client.post<Webhook>(`/api/v2/webhook`, params);\n }\n\n /**\n * List all registered webhooks.\n */\n async list(): Promise<Webhook[]> {\n const res = await this.client.get(`/api/v2/webhook`);\n return res.data ?? res;\n }\n\n /**\n * Update a webhook's callback URL or secret.\n */\n async update(webhookId: string, params: UpdateWebhookParams): Promise<Webhook> {\n sanitizePathParam(webhookId, \"webhookId\");\n return this.client.put<Webhook>(`/api/v2/webhook/${webhookId}`, params);\n }\n\n /**\n * Delete a webhook.\n */\n async delete(webhookId: string): Promise<void> {\n sanitizePathParam(webhookId, \"webhookId\");\n await this.client.del(`/api/v2/webhook/${webhookId}`);\n }\n\n /**\n * Verify a webhook signature from an incoming request.\n * Throws if the signature is invalid.\n *\n * @param body The raw request body (string or Buffer)\n * @param signature The `X-Neutronpay-Signature` header value\n * @param secret Your webhook secret\n * @returns The parsed event payload\n *\n * @example\n * // Express\n * app.post(\"/webhooks/neutron\", express.raw({ type: \"application/json\" }), (req, res) => {\n * try {\n * const event = Neutron.webhooks.verifySignature(\n * req.body,\n * req.headers[\"x-neutronpay-signature\"],\n * \"my-webhook-secret\"\n * );\n * // event is verified and safe to use\n * if (event.txnState === \"completed\") fulfillOrder(event.extRefId);\n * } catch (err) {\n * return res.status(401).send(\"Invalid signature\");\n * }\n * res.status(200).send(\"OK\");\n * });\n */\n static verifySignature(\n body: string | Buffer,\n signature: string | undefined | null,\n secret: string\n ): any {\n if (!signature) {\n throw new NeutronValidationError(\"Missing webhook signature header (X-Neutronpay-Signature)\");\n }\n if (!secret) {\n throw new NeutronValidationError(\"Webhook secret is required for verification\");\n }\n\n const bodyStr = typeof body === \"string\" ? body : body.toString(\"utf8\");\n\n const expected = crypto\n .createHmac(\"sha256\", secret)\n .update(bodyStr)\n .digest(\"hex\");\n\n const sigBuf = Buffer.from(signature);\n const expBuf = Buffer.from(expected);\n const isValid = sigBuf.length === expBuf.length && crypto.timingSafeEqual(sigBuf, expBuf);\n\n if (!isValid) {\n throw new NeutronValidationError(\"Invalid webhook signature\");\n }\n\n return JSON.parse(bodyStr);\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { ExchangeRates } from \"../types.js\";\n\nexport class RatesResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * Get current BTC exchange rates against all supported currencies.\n *\n * @example\n * const rates = await neutron.rates.get();\n * console.log(rates); // { BTCUSD: 97500, BTCVND: 2437500000, ... }\n */\n async get(): Promise<ExchangeRates> {\n const res = await this.client.get(`/api/v2/rate`);\n return res.data ?? res;\n }\n}\n","import type { HttpClient } from \"../client.js\";\nimport type { FiatInstitution, Transaction, SourceOfFunds } from \"../types.js\";\nimport { sanitizePathParam } from \"../sanitize.js\";\n\nexport interface FiatPayoutParams {\n /** Source currency (e.g. \"BTC\") */\n sourceCcy: string;\n /** Amount from source (in BTC for Bitcoin) */\n sourceAmount: number;\n /** Destination fiat currency (e.g. \"VND\") */\n destCcy: string;\n /** Payment method (e.g. \"vnd-instant\") */\n destMethod: string;\n /** Bank account number */\n bankAcctNum: string;\n /** Bank code from `neutron.fiat.institutions()` */\n institutionCode: string;\n /** Recipient legal full name */\n recipientName: string;\n /** Recipient country code (e.g. \"VN\") */\n countryCode: string;\n /** \"individual\" or \"business\" (default: \"individual\") */\n kycType?: \"individual\" | \"business\";\n /** Source of funds declaration */\n sourceOfFunds?: SourceOfFunds;\n /** Your reference ID */\n extRefId?: string;\n}\n\nexport class FiatResource {\n constructor(private readonly client: HttpClient) {}\n\n /**\n * List banks and financial institutions for a country.\n * Returns institution codes needed for fiat payouts.\n *\n * @example\n * const banks = await neutron.fiat.institutions(\"VN\");\n * // [{ code: \"970422\", name: \"MB Bank\" }, ...]\n */\n async institutions(countryCode: string): Promise<FiatInstitution[]> {\n sanitizePathParam(countryCode, \"countryCode\");\n const res = await this.client.get(\n `/api/v2/reference/fiat-institution/by-country/${countryCode}`\n );\n return res.data ?? res;\n }\n\n /**\n * Create a fiat payout transaction. Handles KYC and source of funds automatically.\n * Returns a quoted transaction — call `neutron.transactions.confirm()` to execute.\n *\n * @example\n * const txn = await neutron.fiat.payout({\n * sourceCcy: \"BTC\",\n * sourceAmount: 0.001,\n * destCcy: \"VND\",\n * destMethod: \"vnd-instant\",\n * bankAcctNum: \"0123456789\",\n * institutionCode: \"970422\",\n * recipientName: \"LE VAN A\",\n * countryCode: \"VN\",\n * });\n * // Review rate: txn.fxRate\n * await neutron.transactions.confirm(txn.txnId);\n */\n async payout(params: FiatPayoutParams): Promise<Transaction> {\n return this.client.post<Transaction>(`/api/v2/transaction`, {\n extRefId: params.extRefId,\n sourceReq: {\n ccy: params.sourceCcy,\n method: \"neutronpay\",\n amtRequested: params.sourceAmount,\n reqDetails: {},\n },\n destReq: {\n ccy: params.destCcy,\n method: params.destMethod,\n reqDetails: {\n bankAcctNum: params.bankAcctNum,\n institutionCode: params.institutionCode,\n },\n kyc: {\n type: params.kycType || \"individual\",\n details: {\n legalFullName: params.recipientName,\n countryCode: params.countryCode,\n },\n },\n },\n sourceOfFunds: params.sourceOfFunds ?? {\n purpose: 1,\n source: 5,\n relationship: 3,\n },\n });\n }\n}\n","// ── Satoshi / BTC conversion ────────────────────────────────\n\nconst SATS_PER_BTC = 100_000_000;\n\n/**\n * Convert satoshis to BTC.\n * @example satsToBtc(10000) // 0.0001\n */\nexport function satsToBtc(sats: number): number {\n return sats / SATS_PER_BTC;\n}\n\n/**\n * Convert BTC to satoshis.\n * @example btcToSats(0.0001) // 10000\n */\nexport function btcToSats(btc: number): number {\n return Math.round(btc * SATS_PER_BTC);\n}\n\n/**\n * Format a satoshi amount as a human-readable string.\n * @example formatSats(1500000) // \"1,500,000 sats\"\n * @example formatSats(100) // \"100 sats\"\n */\nexport function formatSats(sats: number): string {\n return `${sats.toLocaleString(\"en-US\")} sats`;\n}\n\n/**\n * Format a BTC amount with appropriate precision.\n * @example formatBtc(0.00015) // \"0.00015000 BTC\"\n */\nexport function formatBtc(btc: number): string {\n return `${btc.toFixed(8)} BTC`;\n}\n\n// ── Constants ───────────────────────────────────────────────\n\n/** Supported currencies */\nexport const Currency = {\n BTC: \"BTC\",\n USDT: \"USDT\",\n VND: \"VND\",\n USD: \"USD\",\n CAD: \"CAD\",\n NGN: \"NGN\",\n KES: \"KES\",\n GHS: \"GHS\",\n} as const;\n\nexport type Currency = (typeof Currency)[keyof typeof Currency];\n\n/** Payment methods for sourceReq/destReq */\nexport const PaymentMethod = {\n /** Internal Neutron wallet */\n NEUTRON: \"neutronpay\",\n /** Lightning Network (BOLT11 invoices) */\n LIGHTNING: \"lightning\",\n /** Lightning Address / LNURL */\n LNURL: \"lnurl\",\n /** Bitcoin on-chain */\n ON_CHAIN: \"on-chain\",\n /** USDT on TRON (TRC-20) */\n TRON: \"tron\",\n /** USDT on Ethereum (ERC-20) */\n ETH: \"eth\",\n /** Vietnamese Dong instant bank transfer */\n VND_INSTANT: \"vnd-instant\",\n} as const;\n\nexport type PaymentMethodType = (typeof PaymentMethod)[keyof typeof PaymentMethod];\n\n/** Transaction final states (terminal — won't change) */\nexport const FinalStates = [\n \"completed\",\n \"expired\",\n \"rejected\",\n \"error\",\n \"usercanceled\",\n] as const;\n\n/** All transaction states */\nexport const TransactionStates = {\n QUOTED: \"quoted\",\n USER_CONFIRMED: \"userconfirmed\",\n SRC_CREATED: \"srccreated\",\n SRC_SENT: \"srcsent\",\n SRC_INTENT: \"srcintent\",\n SRC_PEND_CONFIRM: \"srcpendconfirmfill\",\n SRC_CONFIRMED: \"srcconfirmfilled\",\n DEST_PEND_SENT: \"destpendsent\",\n DEST_SENT: \"destsent\",\n COMPLETED: \"completed\",\n EXPIRED: \"expired\",\n REJECTED: \"rejected\",\n ERROR: \"error\",\n USER_CANCELED: \"usercanceled\",\n} as const;\n\n/** USDT blockchain options */\nexport const Chain = {\n TRON: \"TRON\",\n ETH: \"ETH\",\n} as const;\n","import { HttpClient } from \"./client.js\";\nimport { AccountResource } from \"./resources/account.js\";\nimport { TransactionsResource } from \"./resources/transactions.js\";\nimport { LightningResource } from \"./resources/lightning.js\";\nimport { WebhooksResource } from \"./resources/webhooks.js\";\nimport { RatesResource } from \"./resources/rates.js\";\nimport { FiatResource } from \"./resources/fiat.js\";\nimport type { NeutronConfig } from \"./types.js\";\n\n/**\n * Neutron SDK — Bitcoin Lightning, stablecoins, and fiat payments.\n *\n * @example\n * import { Neutron } from \"neutron-sdk\";\n *\n * const neutron = new Neutron({\n * apiKey: process.env.NEUTRON_API_KEY!,\n * apiSecret: process.env.NEUTRON_API_SECRET!,\n * });\n *\n * // Check balances\n * const wallets = await neutron.account.wallets();\n *\n * // Create a Lightning invoice\n * const invoice = await neutron.lightning.createInvoice({ amountSats: 10000 });\n *\n * // Send to a Lightning Address\n * const txn = await neutron.lightning.payAddress(\"alice@getalby.com\", { amountSats: 5000 });\n * await neutron.transactions.confirm(txn.txnId);\n */\nexport class Neutron {\n /** Account info, wallets, and deposit addresses */\n readonly account: AccountResource;\n /** Create, confirm, list, and track transactions */\n readonly transactions: TransactionsResource;\n /** Lightning invoices, payments, and utilities */\n readonly lightning: LightningResource;\n /** Webhook management */\n readonly webhooks: WebhooksResource;\n /** BTC exchange rates */\n readonly rates: RatesResource;\n /** Fiat payouts and bank lookups */\n readonly fiat: FiatResource;\n\n private readonly client: HttpClient;\n\n constructor(config: NeutronConfig) {\n this.client = new HttpClient(config);\n this.account = new AccountResource(this.client);\n this.transactions = new TransactionsResource(this.client);\n this.lightning = new LightningResource(this.client);\n this.webhooks = new WebhooksResource(this.client);\n this.rates = new RatesResource(this.client);\n this.fiat = new FiatResource(this.client);\n }\n\n /**\n * Explicitly authenticate and verify credentials.\n * Usually not needed — the SDK auto-authenticates on first request.\n */\n async authenticate() {\n return this.client.authenticate();\n }\n\n /**\n * Verify a webhook signature. Static method — no client instance needed.\n *\n * @example\n * const event = Neutron.verifyWebhook(req.body, req.headers[\"x-neutronpay-signature\"], secret);\n */\n static verifyWebhook(body: string | Buffer, signature: string | undefined | null, secret: string) {\n return WebhooksResource.verifySignature(body, signature, secret);\n }\n}\n\n// ── Exports ─────────────────────────────────────────────────\n\nexport { HttpClient } from \"./client.js\";\nexport { AccountResource } from \"./resources/account.js\";\nexport { TransactionsResource } from \"./resources/transactions.js\";\nexport { LightningResource } from \"./resources/lightning.js\";\nexport { WebhooksResource } from \"./resources/webhooks.js\";\nexport { RatesResource } from \"./resources/rates.js\";\nexport { FiatResource } from \"./resources/fiat.js\";\nexport type { FiatPayoutParams } from \"./resources/fiat.js\";\n\nexport { sanitizePathParam } from \"./sanitize.js\";\n\nexport {\n NeutronError,\n NeutronApiError,\n NeutronAuthError,\n NeutronTimeoutError,\n NeutronValidationError,\n} from \"./errors.js\";\n\nexport {\n satsToBtc,\n btcToSats,\n formatSats,\n formatBtc,\n Currency,\n PaymentMethod,\n TransactionStates,\n FinalStates,\n Chain,\n} from \"./utils.js\";\n\nexport type {\n Currency as CurrencyType,\n PaymentMethodType,\n} from \"./utils.js\";\n\nexport type {\n NeutronConfig,\n AuthResponse,\n Account,\n Wallet,\n Transaction,\n TransactionState,\n TransactionSide,\n PaymentMethod as PaymentMethodString,\n CreateTransactionRequest,\n ListTransactionsParams,\n CreateInvoiceParams,\n LightningInvoice,\n BtcAddress,\n UsdtAddress,\n Webhook,\n CreateWebhookParams,\n UpdateWebhookParams,\n ExchangeRates,\n FiatInstitution,\n KycInfo,\n SourceOfFunds,\n ApiResponse,\n} from \"./types.js\";\n"],"mappings":"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","names":["crypto","crypto"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neutron-sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Official Neutron SDK — Bitcoin Lightning, stablecoins, and fiat payments for Node.js and TypeScript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",