neutron-sdk 0.1.4 → 0.1.5
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 +1 -1
- package/dist/index.cjs +12 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +12 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -297,7 +297,7 @@ const neutron = new Neutron({
|
|
|
297
297
|
- **Two-step flow**: `.create()` returns a quote → `.confirm()` executes it.
|
|
298
298
|
- **Set amount on one side only** — `sourceReq` OR `destReq`, not both.
|
|
299
299
|
- **`createInvoice()` auto-confirms** — no second step needed for receiving.
|
|
300
|
-
- **KYC only for fiat payouts**. Lightning
|
|
300
|
+
- **KYC only for fiat payouts**. Bitcoin (Lightning + on-chain), stablecoins (USDT on TRON/ETH), and swaps require **no KYC**.
|
|
301
301
|
- **Token management is automatic** — the SDK authenticates on first request and refreshes as needed.
|
|
302
302
|
|
|
303
303
|
---
|
package/dist/index.cjs
CHANGED
|
@@ -222,9 +222,9 @@ var HttpClient = class {
|
|
|
222
222
|
const url = `${this.baseUrl}${path}`;
|
|
223
223
|
this.log(`${method} ${path}`);
|
|
224
224
|
const headers = {
|
|
225
|
-
Authorization: `Bearer ${this.accessToken}
|
|
225
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
226
|
+
"Content-Type": "application/json"
|
|
226
227
|
};
|
|
227
|
-
if (body) headers["Content-Type"] = "application/json";
|
|
228
228
|
const response = await this.rawFetch(url, {
|
|
229
229
|
method,
|
|
230
230
|
headers,
|
|
@@ -399,10 +399,14 @@ var TransactionsResource = class {
|
|
|
399
399
|
}
|
|
400
400
|
/**
|
|
401
401
|
* Cancel a quoted (unconfirmed) transaction.
|
|
402
|
+
*
|
|
403
|
+
* @deprecated This endpoint is not currently available on the Neutron API.
|
|
404
|
+
* Unconfirmed transactions expire automatically after their TTL.
|
|
402
405
|
*/
|
|
403
|
-
async cancel(
|
|
404
|
-
|
|
405
|
-
|
|
406
|
+
async cancel(_txnId) {
|
|
407
|
+
throw new Error(
|
|
408
|
+
"transactions.cancel() is not available. Unconfirmed transactions expire automatically."
|
|
409
|
+
);
|
|
406
410
|
}
|
|
407
411
|
/**
|
|
408
412
|
* Wait for a transaction to reach a final state. Polls at the given interval.
|
|
@@ -538,7 +542,7 @@ var LightningResource = class {
|
|
|
538
542
|
destReq: {
|
|
539
543
|
ccy: "BTC",
|
|
540
544
|
method: "lnurl",
|
|
541
|
-
reqDetails: {
|
|
545
|
+
reqDetails: { address }
|
|
542
546
|
}
|
|
543
547
|
});
|
|
544
548
|
}
|
|
@@ -667,7 +671,8 @@ var FiatResource = class {
|
|
|
667
671
|
return res.data ?? res;
|
|
668
672
|
}
|
|
669
673
|
/**
|
|
670
|
-
* Create a fiat payout transaction.
|
|
674
|
+
* Create a fiat payout transaction. KYC is required only for fiat payouts — not for
|
|
675
|
+
* Bitcoin, stablecoins, or swaps. Handles KYC and source of funds automatically.
|
|
671
676
|
* Returns a quoted transaction — call `neutron.transactions.confirm()` to execute.
|
|
672
677
|
*
|
|
673
678
|
* @example
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 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"]}
|
|
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 \"Content-Type\": \"application/json\",\n };\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 * @deprecated This endpoint is not currently available on the Neutron API.\n * Unconfirmed transactions expire automatically after their TTL.\n */\n async cancel(_txnId: string): Promise<Transaction> {\n throw new Error(\n \"transactions.cancel() is not available. Unconfirmed transactions expire automatically.\"\n );\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: { 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. KYC is required only for fiat payouts — not for\n * Bitcoin, stablecoins, or swaps. 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;;;ACAA,oBAAmB;;;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,cAAAA,QACJ,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,QACzC,gBAAgB;AAAA,MAClB;AAEA,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;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,QAAsC;AACjD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;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;;;AC3HO,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,QAAQ;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,EACH;AAEF;;;AC1HA,IAAAC,iBAAmB;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,WAAW,eAAAC,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,UAAU,eAAAA,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;AAAA,EAqBA,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;;;AChGA,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;;;AV1EO,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","import_crypto","crypto"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -251,8 +251,11 @@ declare class TransactionsResource {
|
|
|
251
251
|
list(params?: ListTransactionsParams): Promise<Transaction[]>;
|
|
252
252
|
/**
|
|
253
253
|
* Cancel a quoted (unconfirmed) transaction.
|
|
254
|
+
*
|
|
255
|
+
* @deprecated This endpoint is not currently available on the Neutron API.
|
|
256
|
+
* Unconfirmed transactions expire automatically after their TTL.
|
|
254
257
|
*/
|
|
255
|
-
cancel(
|
|
258
|
+
cancel(_txnId: string): Promise<Transaction>;
|
|
256
259
|
/**
|
|
257
260
|
* Wait for a transaction to reach a final state. Polls at the given interval.
|
|
258
261
|
*
|
|
@@ -422,7 +425,8 @@ declare class FiatResource {
|
|
|
422
425
|
*/
|
|
423
426
|
institutions(countryCode: string): Promise<FiatInstitution[]>;
|
|
424
427
|
/**
|
|
425
|
-
* Create a fiat payout transaction.
|
|
428
|
+
* Create a fiat payout transaction. KYC is required only for fiat payouts — not for
|
|
429
|
+
* Bitcoin, stablecoins, or swaps. Handles KYC and source of funds automatically.
|
|
426
430
|
* Returns a quoted transaction — call `neutron.transactions.confirm()` to execute.
|
|
427
431
|
*
|
|
428
432
|
* @example
|
package/dist/index.d.ts
CHANGED
|
@@ -251,8 +251,11 @@ declare class TransactionsResource {
|
|
|
251
251
|
list(params?: ListTransactionsParams): Promise<Transaction[]>;
|
|
252
252
|
/**
|
|
253
253
|
* Cancel a quoted (unconfirmed) transaction.
|
|
254
|
+
*
|
|
255
|
+
* @deprecated This endpoint is not currently available on the Neutron API.
|
|
256
|
+
* Unconfirmed transactions expire automatically after their TTL.
|
|
254
257
|
*/
|
|
255
|
-
cancel(
|
|
258
|
+
cancel(_txnId: string): Promise<Transaction>;
|
|
256
259
|
/**
|
|
257
260
|
* Wait for a transaction to reach a final state. Polls at the given interval.
|
|
258
261
|
*
|
|
@@ -422,7 +425,8 @@ declare class FiatResource {
|
|
|
422
425
|
*/
|
|
423
426
|
institutions(countryCode: string): Promise<FiatInstitution[]>;
|
|
424
427
|
/**
|
|
425
|
-
* Create a fiat payout transaction.
|
|
428
|
+
* Create a fiat payout transaction. KYC is required only for fiat payouts — not for
|
|
429
|
+
* Bitcoin, stablecoins, or swaps. Handles KYC and source of funds automatically.
|
|
426
430
|
* Returns a quoted transaction — call `neutron.transactions.confirm()` to execute.
|
|
427
431
|
*
|
|
428
432
|
* @example
|
package/dist/index.js
CHANGED
|
@@ -164,9 +164,9 @@ var HttpClient = class {
|
|
|
164
164
|
const url = `${this.baseUrl}${path}`;
|
|
165
165
|
this.log(`${method} ${path}`);
|
|
166
166
|
const headers = {
|
|
167
|
-
Authorization: `Bearer ${this.accessToken}
|
|
167
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
168
|
+
"Content-Type": "application/json"
|
|
168
169
|
};
|
|
169
|
-
if (body) headers["Content-Type"] = "application/json";
|
|
170
170
|
const response = await this.rawFetch(url, {
|
|
171
171
|
method,
|
|
172
172
|
headers,
|
|
@@ -341,10 +341,14 @@ var TransactionsResource = class {
|
|
|
341
341
|
}
|
|
342
342
|
/**
|
|
343
343
|
* Cancel a quoted (unconfirmed) transaction.
|
|
344
|
+
*
|
|
345
|
+
* @deprecated This endpoint is not currently available on the Neutron API.
|
|
346
|
+
* Unconfirmed transactions expire automatically after their TTL.
|
|
344
347
|
*/
|
|
345
|
-
async cancel(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
+
async cancel(_txnId) {
|
|
349
|
+
throw new Error(
|
|
350
|
+
"transactions.cancel() is not available. Unconfirmed transactions expire automatically."
|
|
351
|
+
);
|
|
348
352
|
}
|
|
349
353
|
/**
|
|
350
354
|
* Wait for a transaction to reach a final state. Polls at the given interval.
|
|
@@ -480,7 +484,7 @@ var LightningResource = class {
|
|
|
480
484
|
destReq: {
|
|
481
485
|
ccy: "BTC",
|
|
482
486
|
method: "lnurl",
|
|
483
|
-
reqDetails: {
|
|
487
|
+
reqDetails: { address }
|
|
484
488
|
}
|
|
485
489
|
});
|
|
486
490
|
}
|
|
@@ -609,7 +613,8 @@ var FiatResource = class {
|
|
|
609
613
|
return res.data ?? res;
|
|
610
614
|
}
|
|
611
615
|
/**
|
|
612
|
-
* Create a fiat payout transaction.
|
|
616
|
+
* Create a fiat payout transaction. KYC is required only for fiat payouts — not for
|
|
617
|
+
* Bitcoin, stablecoins, or swaps. Handles KYC and source of funds automatically.
|
|
613
618
|
* Returns a quoted transaction — call `neutron.transactions.confirm()` to execute.
|
|
614
619
|
*
|
|
615
620
|
* @example
|
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://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"]}
|
|
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 \"Content-Type\": \"application/json\",\n };\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 * @deprecated This endpoint is not currently available on the Neutron API.\n * Unconfirmed transactions expire automatically after their TTL.\n */\n async cancel(_txnId: string): Promise<Transaction> {\n throw new Error(\n \"transactions.cancel() is not available. Unconfirmed transactions expire automatically.\"\n );\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: { 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. KYC is required only for fiat payouts — not for\n * Bitcoin, stablecoins, or swaps. 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