diff --git a/.gitignore b/.gitignore index 1a131a4..b3d2c0c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ settings.local.json .claude/ *.log .DS_Store +.abi-cache diff --git a/CLAUDE.md b/CLAUDE.md index a94c15a..b508f1c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,13 +40,18 @@ src/ │ ├── defi-client.ts - Main DefiClient class with convenience methods │ └── models/ - Type definitions and mappers for API responses ├── blockchain/ - Blockchain-specific clients -│ └── multisig-client.ts - MultisigBlockchainClient for EIP-712 and transactions +│ ├── multisig-client.ts - MultisigBlockchainClient (EVM, EIP-712) +│ ├── tron-multisig-client.ts - TronMultisigBlockchainClient (TVM, TIP-712) +│ ├── get-chain.ts - Chain resolver utilities +│ └── tron-chains.ts - TRON chain configs (Mainnet, Shasta) └── utils/ - Utilities - ├── transactions/ - Transaction builders and EIP-712 helpers - └── validation.ts - Address validation utilities + ├── transactions/ - EIP-712 / TIP-712 builders, signature packing + ├── validation.ts - EVM address validation + ├── tron-validation.ts - TRON address validation + └── tron-types.ts - Branded TronAddress type generated-contracts/ - OpenAPI-generated DTOs and API classes (DO NOT EDIT) -examples/ - Runnable example scripts +examples/ - Runnable example scripts (EVM and TRON) docs/ - Extended documentation (overview, API client, transactions, contributing) ``` @@ -56,53 +61,63 @@ docs/ - Extended documentation (overview, API client, transactions, The main entry point for REST API interactions. Instantiate with `baseUrl` and `apiKey`: ```ts const client = new DefiClient({ - baseUrl: 'https://api.example.com', + baseUrl: 'https://api.defi.b2binpay.com', apiKey: process.env.API_KEY!, + abiCacheDir: '.abi-cache', // optional disk cache for contract ABIs }); ``` **Important patterns:** -- **Account selection**: The API key maps to a single account, so `accountId` is auto-resolved internally. Call `getAccount()` to fetch account details. -- **Chain selection**: Call `await client.selectChain(chainId)` to cache the deployment for a chain. Subsequent invoice/payout/claim methods use this cached deployment unless `chainId` is explicitly passed per method. -- **Automatic header injection**: The client automatically adds `x-api-key` header to all requests. +- **Account resolution**: API key maps to one account — `accountId` is never required. +- **Chain selection**: `selectChain(chainId)` caches the deployment; subsequent invoice/payout/claim calls omit `chainId`. +- **ABI caching**: `getContractAbi()` fetches and caches the multisig ABI (memory + optional disk). Pass result to blockchain clients. -Key methods include: -- `getAccounts()`, `getAccount()`, `getDeployments()` -- `selectChain(chainId)` - Cache deployment for chain-scoped operations +Key methods: +- `getAccounts()`, `getAccount()`, `getDeployments()`, `selectChain()`, `getContractAbi()` - `getAccountBalanceSummary()`, `getAssetBalances()` - `createInvoice()`, `getInvoices()`, `getInvoice()`, `updateInvoice()` -- `createPayout()`, `getPayouts()`, `getPayout()` +- `createPayout()`, `getPayouts()`, `getPayout()`, `updatePayout()` - `getClaims()`, `getClaimableCurrencies()` -- `findCurrencyBySymbol()`, `getNativeCurrency()` +- `getTransactions()`, `getTransaction()` +- `findCurrencyBySymbol()`, `getNativeCurrency()`, `getCurrencies()` - `getDeploymentQueue()`, `submitOperationSignature()` #### MultisigBlockchainClient (`src/blockchain/multisig-client.ts`) -Handles blockchain-specific operations for multisig contracts: -- `createExecuteTypedData()` - Build EIP-712 typed data for signing operations -- `buildExecuteTransaction()` - Prepare execute transaction for one or more operations -- `buildClaimCalldata()` - Generate calldata for claim/claimTo functions +EVM multisig operations (EIP-712 signing, execute transactions, claim calldata): +- `createExecuteTypedData({ contractAddress, operation })` - Build EIP-712 typed data +- `buildExecuteTransaction({ contractAddress, operations })` - Encode execute() call +- `buildClaimCalldata({ erc20, depositAccountIds, to? })` - Generate claim calldata -Requires a `viem` `PublicClient` instance for reading contract state and chain ID. +Requires a viem `PublicClient` and `AbiCacheEntry` from `client.getContractAbi()`. -#### Transaction Utilities (`src/utils/transactions/`) -- `eip712.ts` - EIP-712 domain/message builders for multisig execute operations -- `builders.ts` - Transaction builders for execute operations +#### TronMultisigBlockchainClient (`src/blockchain/tron-multisig-client.ts`) +TVM multisig operations (TIP-712 signing, execute/claim transactions): +- `createExecuteTypedData({ contractAddress, operation })` - Build TIP-712 typed data +- `buildExecuteTransaction({ contractAddress, callerAddress, operations })` - Encode Tron execute +- `buildClaimTransaction({ contractAddress, callerAddress, erc20, depositIds })` - Encode Tron claim + +Requires a `TronWeb` instance, `AbiCacheEntry`, and `defaultFeeLimit` (in SUN). -These are consumed by `MultisigBlockchainClient` but can also be used directly. +#### Transaction Utilities (`src/utils/transactions/`) +- `eip712.ts` - EIP-712 builders for EVM (createExecuteTypedData, buildExecuteTypedMessage, signExecuteTypedData) +- `tron-tip712.ts` - TIP-712 builders for TVM (buildTronExecuteTypedData, prepareTronTypedDataForSigning) +- `builders.ts` - Low-level transaction encoders (buildExecuteOperationsTransaction, packSignatures, packTronSignatures) ### Typical Workflow -1. **Authentication**: Create `DefiClient` with API key -2. **Chain Selection**: Call `client.selectChain(chainId)` to set active chain -3. **API Operations**: Use client methods for invoices, payouts, claims -4. **Blockchain Operations**: - - Create `MultisigBlockchainClient` with `PublicClient` +1. **Authentication**: Create `DefiClient` with API key and base URL +2. **Chain Selection**: `client.selectChain(chainId)` to cache deployment +3. **ABI**: `client.getContractAbi()` to fetch contract ABI (required for blockchain clients) +4. **Blockchain Operations** (EVM): + - Create `MultisigBlockchainClient` with `publicClient` and `contractAbi` - Build EIP-712 typed data with `createExecuteTypedData()` - Sign with wallet's `signTypedData()` - - Submit signature via `client.submitOperationSignature()` + - Submit via `client.submitOperationSignature()` (auto-packs) - Execute via `buildExecuteTransaction()` and broadcast +5. **Blockchain Operations** (TRON): + - Same flow with `TronMultisigBlockchainClient` and TronWeb -See `examples/queue-sign.ts` and `examples/queue-execute.ts` for complete flows. +See `examples/evm-full-flow.ts` and `examples/tron-full-flow.ts` for complete flows. ### Generated vs Hand-Written Code @@ -133,13 +148,14 @@ See `examples/queue-sign.ts` and `examples/queue-execute.ts` for complete flows. ## Testing Strategy -No test suite is currently present. When adding tests: -- Test files should be `*.test.ts` +Run tests with `npx jest --passWithNoTests`. Config: `jest.config.mjs`. + +- Test files: `*.spec.ts` or `*.test.ts` - `noExplicitAny` linting rule is disabled for test files (see `biome.json` overrides) ## Publishing -- Version is set to `"auto"` in `package.json` - likely managed by CI +- Version is set to `"auto"` in `package.json` — managed by CI - `npm run prepublishOnly` runs build automatically - Exported files: `dist/`, `docs/`, `README.md` - Entry points defined in `exports` field for CommonJS/ESM compatibility diff --git a/README.md b/README.md index 908c87e..68423eb 100644 --- a/README.md +++ b/README.md @@ -1,179 +1,305 @@ -# SDK +# @b2binpay/defi-sdk + +[![npm version](https://img.shields.io/npm/v/@b2binpay/defi-sdk.svg)](https://www.npmjs.com/package/@b2binpay/defi-sdk) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) +[![Node.js](https://img.shields.io/badge/node-%5E22.16.0-brightgreen)](https://nodejs.org) + +TypeScript SDK for the [B2BinPay DeFi](https://defi.b2binpay.com) platform — authenticated REST API access and blockchain transaction utilities for building non-custodial payment flows with multisig smart contracts. + +## Features + +- **Multi-chain** — EVM-compatible networks (Ethereum, BSC, Sepolia, …) and TRON (Mainnet, Shasta) +- **Invoices & Payouts** — full lifecycle management: create, query, update, cancel +- **Multisig operations** — EIP-712 / TIP-712 typed-data signing, signature packing, on-chain execution +- **Claims** — enumerate claimable deposits and build claim calldata +- **Address validation** — checksum + network + currency compatibility checks before write operations +- **Type-safe** — complete TypeScript types from the OpenAPI spec plus handcrafted blockchain types +- **Built on viem** — EVM blockchain interactions powered by [viem](https://viem.sh) + +## Requirements + +- Node.js `^22.16.0` +- npm `^10.9.2` + +## Installation + +```sh +npm install @b2binpay/defi-sdk +``` + +TRON support (`TronMultisigBlockchainClient`) is included out of the box — `tronweb` is bundled as a dependency. ## Quick Start -All API calls are authenticated via an API key supplied in the `x-api-key` header. Pass the key when creating `DefiClient` and the SDK will attach it automatically. +```ts +import { DefiClient, FiatCurrency } from '@b2binpay/defi-sdk'; + +const client = new DefiClient({ + baseUrl: 'https://api.defi.b2binpay.com', + apiKey: process.env.API_KEY!, +}); + +// Select the active chain (caches the deployment for subsequent calls) +await client.selectChain(1); // Ethereum Mainnet + +// Query balance +const balance = await client.getAccountBalanceSummary({ + chainId: 1, + baseCurrency: FiatCurrency.Usd, +}); +console.log('Total balance (USD):', balance.totalBalance); + +// Resolve a currency and create an invoice +const usdt = await client.findCurrencyBySymbol({ symbol: 'USDT', chainId: 1 }); +const invoice = await client.createInvoice({ + requestedAmount: '100', + currencyIds: [usdt.id], + callbackUrl: 'https://merchant.example/webhook', + trackingId: 'order-42', +}); +console.log('Invoice ID:', invoice.id); +``` + +## Authentication + +All requests use an API key sent as the `x-api-key` header. Pass it once at construction — the SDK attaches it to every request automatically. No token exchange or refresh is required. + +Each API key is scoped to a single account. The SDK resolves the account and deployment IDs internally; you never need to pass `accountId` explicitly. + +## EVM — Multisig Operation Flow + +Payouts are executed on-chain through a multisig wallet. The typical flow is: + +1. **Create a payout** — the API enqueues a multisig operation +2. **Fetch the queue** — retrieve the pending operation +3. **Build EIP-712 typed data and sign** — produce the off-chain approval +4. **Submit the signature** — the API records approval; once the signing threshold is met the operation becomes executable +5. **Execute on-chain** — broadcast the `execute` transaction ```ts +import { createPublicClient, http } from 'viem'; import { - FiatCurrency, - InvoiceStatus, - PayoutStatus, DefiClient, + MultisigBlockchainClient, + getEvmChainById, + QueueOperationStatus, } from '@b2binpay/defi-sdk'; +import { privateKeyToAccount } from 'viem/accounts'; + +const CHAIN_ID = 11155111; // Sepolia const client = new DefiClient({ - baseUrl: 'https://api.example.com', + baseUrl: 'https://api.defi.b2binpay.com', apiKey: process.env.API_KEY!, }); -async function bootstrap() { - const accounts = await client.getAccounts(); - console.log('Discovered accounts via API key:', accounts.map((account) => account.name)); - - const accountDetails = await client.getAccount(); - const deployments = await client.getDeployments(accountDetails); - console.log('Available deployments:', deployments.map((item) => `${item.chainId}:${item.deploymentStatus}`)); - const deployment = await client.selectChain(1); - const balance = await client.getAccountBalanceSummary({ - chainId: 1, - baseCurrency: FiatCurrency.Usd, - }); - - console.log(accountDetails.account.name, balance.totalBalance); - console.log('Active deployment:', deployment.deploymentId); - - // Need chain-specific helpers? - const nativeCurrency = await client.getNativeCurrency(1); - const invoices = await client.getInvoices({ - statuses: [InvoiceStatus.Created], - pageSize: 10, - }); -} +// Step 1: resolve deployment and ABI +const deployment = await client.selectChain(CHAIN_ID); +const contractAbi = await client.getContractAbi(); + +// Step 2: create payout +const currency = await client.getNativeCurrency(CHAIN_ID); +await client.createPayout({ + currencyId: currency.id, + amount: '0.001', + recipient: '0xRecipientAddress', +}); + +// Step 3: set up viem and the multisig client +const chain = getEvmChainById(String(CHAIN_ID), process.env.RPC_URL!); +const publicClient = createPublicClient({ chain, transport: http(process.env.RPC_URL!) }); + +const multisig = new MultisigBlockchainClient({ chainId: String(CHAIN_ID), publicClient, contractAbi }); + +// Step 4: sign +const { items } = await client.getDeploymentQueue({}); +const operation = items.find((op) => op.status === QueueOperationStatus.Pending); + +const typedData = await multisig.createExecuteTypedData({ + contractAddress: deployment.contract as `0x${string}`, + operation, +}); + +const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); +const rawSignature = await account.signTypedData(typedData); -bootstrap(); +await client.submitOperationSignature({ + operationId: operation.executeOperationId, + signature: rawSignature, + signerAddress: account.address, +}); + +// Step 5: execute (once ready) +const readyQueue = await client.getDeploymentQueue({}); +const readyOp = readyQueue.items.find((op) => op.status === QueueOperationStatus.Ready); + +const tx = multisig.buildExecuteTransaction({ + contractAddress: deployment.contract as `0x${string}`, + operations: [readyOp], +}); + +// Broadcast with a viem WalletClient +import { createWalletClient } from 'viem'; +const walletClient = createWalletClient({ account, chain, transport: http(process.env.RPC_URL!) }); +const hash = await walletClient.sendTransaction(tx); ``` -### Invoices, Payouts & Transactions +See [`examples/evm-full-flow.ts`](examples/evm-full-flow.ts) for a complete runnable walkthrough including automatic deposit and confirmation polling. + +## TRON — Multisig Operation Flow + +The TRON flow mirrors EVM but uses `TronMultisigBlockchainClient` and `tronweb` for signing and broadcasting. ```ts -import { PayoutStatus } from '@b2binpay/defi-sdk'; +import TronWeb from 'tronweb'; +import { DefiClient, TronMultisigBlockchainClient, QueueOperationStatus } from '@b2binpay/defi-sdk'; -await client.selectChain(1); +const CHAIN_ID = 728126428; // TRON Mainnet (2494104990 for Shasta) -const usdCoin = await client.findCurrencyBySymbol({ symbol: 'USDT', chainId: 1 }); +const client = new DefiClient({ + baseUrl: 'https://api.defi.b2binpay.com', + apiKey: process.env.API_KEY!, +}); -const invoice = await client.createInvoice({ - requestedAmount: '100', - currencyIds: [usdCoin.id], - callbackUrl: 'https://merchant.example/callback', - trackingId: 'INV-42', +const deployment = await client.selectChain(CHAIN_ID); +const contractAbi = await client.getContractAbi(); + +const tronWeb = new TronWeb({ + fullHost: process.env.RPC_URL!, + privateKey: process.env.WALLET_PRIVATE_KEY, +}); + +const multisig = new TronMultisigBlockchainClient({ + chainId: String(CHAIN_ID), + tronWeb, + contractAbi, + defaultFeeLimit: 150_000_000, // 150 TRX in SUN }); -// To cancel an invoice, use updateInvoice to set status to CANCELLED -await client.updateInvoice({ - invoiceId: invoice.id, - status: InvoiceStatus.Cancelled +// Sign +const { items } = await client.getDeploymentQueue({}); +const operation = items.find((op) => op.status === QueueOperationStatus.Pending); + +const typedData = await multisig.createExecuteTypedData({ + contractAddress: deployment.contract, + operation, }); -const payouts = await client.getPayouts({ - statuses: [PayoutStatus.Created], +const rawSignature = await tronWeb.trx.signMessageV2(typedData.message); +await client.submitOperationSignature({ + operationId: operation.executeOperationId, + signature: rawSignature, + signerAddress: tronWeb.defaultAddress.base58, }); -const transactions = await client.getTransactions({ - operationTypes: ['payout'], - pageSize: 20, +// Execute +const readyOp = (await client.getDeploymentQueue({})).items.find( + (op) => op.status === QueueOperationStatus.Ready, +); +const tx = await multisig.buildExecuteTransaction({ + contractAddress: deployment.contract, + callerAddress: tronWeb.defaultAddress.base58, + operations: [readyOp], }); +const broadcast = await tronWeb.trx.sendRawTransaction(tx.raw); ``` -### Claims & Address Validation +See [`examples/tron-full-flow.ts`](examples/tron-full-flow.ts) for the complete TRON walkthrough. -```ts -import { validateAddress } from '@b2binpay/defi-sdk'; +## Claims -const chainId = 1; -await client.selectChain(chainId); +Deposits received to the multisig wallet must be explicitly claimed on-chain. +```ts +// List claimable deposits grouped by currency const claims = await client.getClaims({}); -const currencies = await client.getClaimableCurrencies(); +const depositIds = claims.items.map((c) => c.invoiceNonce); + +const claimable = await client.getClaimableCurrencies(); -// Use MultisigBlockchainClient.buildClaimCalldata() to build claim transactions -// See examples/claim-deposits.ts for complete claim flow +// Build calldata +const calldata = multisig.buildClaimCalldata({ + erc20: claimable[0].address as `0x${string}`, + depositAccountIds: depositIds, + to: recipientAddress, // optional — omit to claim to the multisig contract itself +}); -const { isValid, errors } = validateAddress({ - address: env.PAYOUT_RECIPIENT, - networkChainId: chainId, - currency: currencies[0], +// Broadcast using walletClient +const hash = await walletClient.sendTransaction({ + to: deployment.contract as `0x${string}`, + data: calldata, }); ``` -### Blockchain Helpers +For TRON, use `multisig.buildClaimTransaction(...)` and broadcast with `tronWeb.trx.sendRawTransaction(tx.raw)`. -When you need to prepare multisig payloads or read on-chain state, instantiate the blockchain-specific client: +## Address Validation + +Use `validateAddress` before submitting payouts or invoices to catch format and network mismatches early. ```ts -import { MultisigBlockchainClient } from '@b2binpay/defi-sdk'; -import { createPublicClient, defineChain, http } from 'viem'; - -const publicClient = createPublicClient({ - chain: defineChain({ - id: 1, - name: 'mainnet', - network: 'mainnet', - nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, - rpcUrls: { - default: { http: [process.env.RPC_URL!] }, - public: { http: [process.env.RPC_URL!] }, - }, - }), - transport: http(process.env.RPC_URL!), -}); - -const multisig = new MultisigBlockchainClient({ - chainId: 1, - publicClient, -}); +import { validateAddress } from '@b2binpay/defi-sdk'; -const typedData = await multisig.createExecuteTypedData({ - contractAddress: deployment.contract as `0x${string}`, - operation, +const { isValid, errors, normalizedAddress } = validateAddress({ + address: recipientAddress, + networkChainId: CHAIN_ID, + currency: selectedCurrency, }); -const signature = await wallet.signTypedData(typedData); +if (!isValid) { + console.error('Invalid address:', errors); +} ``` -## CLI Scripts -- `npm run example:get-account-info` – authenticates, lists deployments, prints per-chain balance summaries, and shows non-zero asset balances. -- `npm run example:create-invoice` – creates an invoice (currency resolved by ID or symbol), applies optional callbacks, and prints invoice details. -- `npm run example:get-invoice-details` – lists invoices by filters, fetches invoice details by ID, shows recent deposits, and prints claimable assets. -- `npm run example:create-payout` – creates a payout and surfaces the queue operation for later signing/execution. -- `npm run example:queue-sign` – finds the first signable operation, builds EIP-712 typed data, signs, and submits the signature. -- `npm run example:queue-execute` – finds the first executable operation, builds an execute transaction, broadcasts it, and waits for confirmation. -- `npm run example:queue-execute-batch` – if two operations are executable, executes them together in one transaction. -- `npm run example:claim-deposits` – enumerates claimable deposits, builds claim calldata, broadcasts the transaction, and fetches recent claim activity. -- `npm run generate:api` – regenerate `generated-contracts/` from the OpenAPI spec. - -### Examples -- `examples/get-account-info.ts` – authenticate via API key, discover accounts, list deployments, and show balance summaries plus non-zero assets. -- `examples/create-invoice.ts` – create an invoice with callbacks and tracking metadata using a currency ID or symbol lookup. -- `examples/get-invoice-details.ts` – filter invoices, fetch invoice details by ID, inspect recent incoming transactions, and list claimable assets. -- `examples/create-payout.ts` – authenticate, create a payout, and surface its queue operation for follow-up signing/execution. -- `examples/queue-sign.ts` – locate a signable queue operation, build EIP-712 typed data, and submit a signature. -- `examples/queue-execute.ts` – find the first executable operation, broadcast the execute transaction, and wait for confirmation. -- `examples/queue-execute-batch.ts` – execute two ready operations in a batch using one transaction. -- `examples/claim-deposits.ts` – enumerate claimable invoices, build and broadcast a claim transaction, and fetch recent claim transactions. - -### Environment Variables -- `API_BASE_URL`, `API_KEY` – REST endpoint and API key used for authenticated requests. -- `CHAIN_ID` – EVM chain identifier. -- `BALANCE_BASE_CURRENCY` – optional base currency (`usd`/`eur`/`cny`) for balance summaries in `get-account-info`. -- `WALLET_PRIVATE_KEY` – local hex key for signing multisig transactions (queue-sign/queue-execute). -- `RPC_URL` – JSON-RPC endpoint for the target chain (queue-sign/queue-execute examples). -- `PAYOUT_AMOUNT_WEI` or `PAYOUT_AMOUNT` – payout amount (preferred in wei; falls back to decimal string). -- `PAYOUT_CURRENCY_ID`, `PAYOUT_RECIPIENT`, `PAYOUT_CALLBACK_URL`, `PAYOUT_TRACKING_ID` – payout configuration (currency defaults to native if not provided). -- `INVOICE_CURRENCY_ID`, `INVOICE_CURRENCY_SYMBOL` – pick one to resolve invoice currency; symbol lookup filters by chain. -- `INVOICE_AMOUNT`, `INVOICE_CALLBACK_URL`, `INVOICE_TRACKING_ID`, `INVOICE_PAYMENT_PAGE_URL`, `INVOICE_PAYMENT_PAGE_TEXT` – invoice creation metadata. -- `INVOICE_ID` – target invoice for `get-invoice-details`. -- `INVOICE_STATUSES`, `INVOICE_CREATED_FROM`, `INVOICE_CREATED_TO`, `INVOICE_UPDATED_FROM`, `INVOICE_UPDATED_TO`, `INVOICE_PAGE_SIZE`, `INVOICE_TRACKING_ID`, `INVOICE_CURRENCY_ID` – invoice listing filters for `get-invoice-details`. -- `CLAIM_INVOICE_ID`, `CLAIM_CURRENCY_ID`, `CLAIM_PAGE_SIZE` – optional filters for claimable deposits in `claim-deposits`; calldata is built automatically via `MultisigBlockchainClient.buildClaimCalldata`. -- Account ownership is implicit—each API key maps to a single account, so the SDK auto-selects it and never asks for an `accountId`. -- Call `await client.selectChain(Number(process.env.CHAIN_ID))` (or pass `chainId` per method) before invoking any chain-scoped APIs such as invoices, payouts, or claims. +The helper validates: +- EVM checksum (EIP-55) and format +- TRON Base58Check format and T-prefix +- Network / chain compatibility +- Currency match against the provided asset list + +## Running the Examples + +Clone the repository, install dependencies, and create a `.env` file: + +```sh +git clone https://github.com/b2binpay/defi-sdk-nodejs.git +cd defi-sdk-nodejs +npm install +cp .env.example .env +# Edit .env with your API_BASE_URL, API_KEY, CHAIN_ID, RPC_URL, WALLET_PRIVATE_KEY +``` + +Available scripts: + +| Script | Description | +| ----------------------------------------- | ------------------------------------------------------------------- | +| `npm run example:get-account-info` | List deployments and per-chain balances | +| `npm run example:create-invoice` | Create an invoice with currency lookup | +| `npm run example:get-invoice-details` | Filter invoices, inspect deposits, show claimable assets | +| `npm run example:create-payout` | Create a payout and surface the queued operation | +| `npm run example:queue-sign` | Build EIP-712 typed data, sign, and submit the signature | +| `npm run example:queue-execute` | Build and broadcast an execute transaction | +| `npm run example:queue-execute-batch` | Execute two operations in a single transaction | +| `npm run example:claim-deposits` | Build and broadcast a claim transaction | +| `npm run example:evm-full-flow` | End-to-end EVM flow: invoice → payout → sign → execute → claim | +| `npm run example:tron-get-account-info` | TRON account info and balances | +| `npm run example:tron-full-flow` | End-to-end TRON flow | ## Documentation -Extended documentation lives in the `docs/` folder: -- `docs/overview.md` – high-level summary of the SDK. -- `docs/api-client.md` – authentication flow, configuration options, and caching details. -- `docs/transactions.md` – roadmap and reference for the transaction helper layer. -- `docs/contributing.md` – repository conventions, build scripts, and release guidelines. -Start with `docs/overview.md` for guidance on how the pieces fit together and where to contribute. +| Document | Contents | +| ------------------------------------------ | ----------------------------------------------------------------- | +| [`docs/overview.md`](docs/overview.md) | Architecture overview and high-level workflow | +| [`docs/api-client.md`](docs/api-client.md) | `DefiClient` configuration, all methods, error handling | +| [`docs/transactions.md`](docs/transactions.md) | Transaction helpers, EIP-712/TIP-712, signature packing | +| [`docs/contributing.md`](docs/contributing.md) | Repository setup, coding guidelines, release process | + +## Contributing + +See [`docs/contributing.md`](docs/contributing.md) for repository conventions, build setup, and how to run the examples locally. + +Bug reports and pull requests are welcome at [github.com/b2binpay/defi-sdk-nodejs](https://github.com/b2binpay/defi-sdk-nodejs/issues). + +## License + +MIT — see [LICENSE](LICENSE). diff --git a/docs/api-client.md b/docs/api-client.md index 872ac2b..bb8eb7f 100644 --- a/docs/api-client.md +++ b/docs/api-client.md @@ -1,74 +1,217 @@ # API Client -The API layer is implemented in `src/api/defi-client.ts` and wraps the generated contracts to present a developer-friendly interface for authentication and API calls. +`DefiClient` (`src/api/defi-client.ts`) is the main entry point for all REST API interactions. It wraps the generated OpenAPI client with a developer-friendly interface. ## Configuration ```ts +import { DefiClient } from '@b2binpay/defi-sdk'; + const client = new DefiClient({ - baseUrl: 'https://api.example.com', + baseUrl: 'https://api.defi.b2binpay.com', apiKey: process.env.API_KEY!, - defaultHeaders: { 'x-app-version': '1.0.0' }, }); ``` -Supported options: -- `baseUrl` (required): REST endpoint (without trailing slash). -- `apiKey` (required): value sent as the `x-api-key` header on every request. -- `fetchApi`: Custom fetch implementation (useful for SSR or testing). -- `middleware`: OpenAPI middleware applied to every request. -- `defaultHeaders`, `credentials`, `queryParamsStringify`: Fine-grained HTTP control. +All constructor options: + +| Option | Required | Description | +|------------------------|----------|---------------------------------------------------------| +| `baseUrl` | yes | REST endpoint base URL | +| `apiKey` | yes | Sent as `x-api-key` header on every request | +| `fetchApi` | no | Custom fetch implementation (useful for testing or SSR) | +| `middleware` | no | OpenAPI middleware applied to every request | +| `defaultHeaders` | no | Extra headers merged into every request | +| `credentials` | no | Fetch `credentials` setting | +| `queryParamsStringify` | no | Custom query parameter serializer | +| `abiCacheDir` | no | Directory for persistent ABI disk cache | ## Authentication -`DefiClient` authenticates purely via API key. Provide the key at construction time and every request will include `x-api-key: `. There is no nonce/signature exchange or access/refresh token management in the SDK anymore. - -## Account Management -- `getAccounts()` retrieves all accounts linked to the authenticated user (the first entry is cached automatically). -- `getAccount()` fetches account details as an `AccountDetailsDto`, exposing the primary `account` metadata plus network `deployments`. -- `getDeployments(accountDetails?)` returns the list of deployments for the account; pass cached account details to avoid re-fetching if you already have them. -- `selectChain(chainId)` resolves and stores the deployment for a chain so downstream calls (invoices, payouts, claims, etc.) can omit chain/deployment identifiers. -- `getSelectedDeployment()` returns the cached deployment (or `undefined` if none was selected yet). -- `getAccountBalanceSummary({ chainId, baseCurrency })` retrieves balances; `baseCurrency` must be a value from `FiatCurrency`. -- `getAssetBalances({ chainId?, baseCurrency, ...filters })` returns paginated asset balances with optional sorting/filtering by asset id or balance. -- `getDeploymentByChain(chainId, accountDetails?)` resolves the `AccountDeploymentDto` for the requested chain without affecting the cached selection (pass cached account details to avoid re-fetching). - -Each API key is scoped to a single account, so the SDK auto-selects it internally and never requires an `accountId`. - -## Currencies & Payouts -- `getCurrencies()` returns the list of supported currencies (native coins have `address === null`). -- `getNativeCurrency(chainId)` returns the native coin entry for a chain (i.e., the currency with `address === null`). -- `findCurrencyBySymbol({ symbol, chainId? })` searches currencies by ticker symbol (optionally constrained by chain, or falling back to the selected chain if one is cached); throws if zero or multiple matches exist. -- `createPayout({ currencyId, amount, recipient, ... })` creates a payout request and enqueues a multisig operation for the selected chain (optionally override via `chainId`; amount is passed through as-is to the REST API). -- `getPayouts({ ...filters, chainId? })` lists payouts with rich filtering (status, creator, address, etc.). -- `getPayout({ payoutId, chainId? })` retrieves on-chain and API metadata for a specific payout. -- `updatePayout({ payoutId, ...patch, chainId? })` patches tracking or callback metadata without re-creating the payout. -- `getDeploymentQueue({ chainId?, ... })` fetches pending operations for signature/execution. -- `submitOperationSignature({ operationId, signature, chainId? })` uploads an off-chain signature for an operation. - -## Invoice Management -- `getInvoices({ ...filters, chainId? })` paginates invoices by status, date range, currency, or tracking ID. -- `getInvoice({ invoiceId, chainId? })` returns the full invoice details payload. -- `createInvoice({ requestedAmount, currencyIds, ... , chainId? })` creates an invoice for a chain/currency pair with optional callbacks. -- `updateInvoice({ invoiceId, ...patch, chainId? })` updates request amount, callback URLs, currency selections, or status (e.g., to cancel an invoice, set `status: InvoiceStatus.Cancelled`). - -## Transactions & Claims -- `getTransactions({ ...filters, chainId? })` exposes the transaction ledger with filters for operation type, status, currency, block hash, etc. -- `getTransaction({ transactionId, chainId? })` hydrates a specific transaction with decoded metadata. -- `getClaims({ ...filters, chainId? })` lists claimable deposits grouped by invoice and currency. -- `getClaimableCurrencies(chainId?)` surfaces currencies that currently have claimable balances. -- On-chain claim broadcasting is app-controlled; use `MultisigBlockchainClient.buildClaimCalldata` (see `examples/claim-deposits.ts`) to assemble calldata for `MultiSigWallet.claim`/`claimTo`, then broadcast the transaction yourself. - -## Blockchain Client & Builders -- `MultisigBlockchainClient` (in `src/blockchain`) encapsulates RPC access for multisig operations. -- `createExecuteTypedData({ contractAddress, operation, domainOverride? })` returns the EIP-712 payload ready for `signTypedData`. -- `buildExecuteTransaction({ contractAddress, operations })` builds a `MultiSigWallet.execute` transaction (single or batch) using queue operations. -- `buildClaimCalldata({ erc20, depositAccountIds, to? })` generates calldata for `claim`/`claimTo` functions. - -The lower-level builders in `src/utils/transactions` are also exported if you want to construct transactions without instantiating a client. This separation keeps API usage decoupled from blockchain access so the blockchain client can be used independently of how requests are authenticated. +`DefiClient` authenticates purely via API key. Every request automatically includes the `x-api-key` header — no token exchange, nonce signing, or refresh is required. + +Each API key is scoped to a single account. The SDK resolves and caches the account internally; you never need to pass `accountId` to any method. + +## Account & Deployment Management + +```ts +// Fetch account details (account metadata + deployments) +const accountDetails = await client.getAccount(); + +// Resolve deployments +const deployments = await client.getDeployments(accountDetails); + +// Cache the deployment for a chain — subsequent chain-scoped calls omit chainId +const deployment = await client.selectChain(1); + +// Retrieve the cached deployment without selecting a new one +const cached = client.getSelectedDeployment(); + +// Resolve a specific deployment without affecting the cache +const sepolia = await client.getDeploymentByChain(11155111); +``` + +## Contract ABI + +`getContractAbi` fetches the multisig contract ABI for the selected deployment. The contract version (v1.0.0, v1.1.0, …) is auto-detected from the deployment and determines the signature packing format used by `submitOperationSignature`. The result is cached in memory; pass `abiCacheDir` at construction to also persist it to disk across restarts. + +```ts +// Uses the version associated with the selected deployment (call selectChain first) +const contractAbi = await client.getContractAbi(); + +// Or request a specific version explicitly +const contractAbi = await client.getContractAbi('1.0.0'); +``` + +Pass the result directly to `MultisigBlockchainClient` or `TronMultisigBlockchainClient`. + +## Balances & Assets + +```ts +import { FiatCurrency, AssetSortField, SortOrder } from '@b2binpay/defi-sdk'; + +// Fiat-converted totals for a chain +const summary = await client.getAccountBalanceSummary({ chainId: 1, baseCurrency: FiatCurrency.Usd }); + +// Paginated asset balances +const assets = await client.getAssetBalances({ + chainId: 1, + baseCurrency: FiatCurrency.Usd, + sortField: AssetSortField.Balance, + sortOrder: SortOrder.Desc, + pageSize: 20, +}); +``` + +## Currencies + +```ts +// All supported currencies on all chains +const currencies = await client.getCurrencies(); + +// Native coin for a chain (address === null) +const eth = await client.getNativeCurrency(1); + +// Lookup by ticker (throws if zero or multiple matches) +const usdt = await client.findCurrencyBySymbol({ symbol: 'USDT', chainId: 1 }); +``` + +> **Note (TRON):** On TRON, `getCurrencies()` may return stale EVM-format entries. Use `getNativeCurrency(chainId)` to get TRX reliably. + +## Invoices + +```ts +import { InvoiceStatus } from '@b2binpay/defi-sdk'; + +// Create +const invoice = await client.createInvoice({ + requestedAmount: '100', + currencyIds: [usdt.id], + callbackUrl: 'https://merchant.example/webhook', + trackingId: 'order-42', + // chainId: 1 — uses selected chain if omitted +}); + +// List with filters +const open = await client.getInvoices({ + statuses: [InvoiceStatus.Created], + pageSize: 20, + createdFrom: new Date('2024-01-01'), +}); + +// Fetch details +const details = await client.getInvoice({ invoiceId: invoice.id }); + +// Update (cancel, patch amount or callback URL) +await client.updateInvoice({ + invoiceId: invoice.id, + status: InvoiceStatus.Cancelled, +}); +``` + +## Payouts + +```ts +import { PayoutStatus } from '@b2binpay/defi-sdk'; + +// Create — enqueues a multisig operation +const payout = await client.createPayout({ + currencyId: usdt.id, + amount: '50', + recipient: '0xRecipientAddress', + trackingId: 'payout-001', + callbackUrl: 'https://merchant.example/webhook', +}); + +// List +const payouts = await client.getPayouts({ statuses: [PayoutStatus.Created] }); + +// Fetch with on-chain metadata +const details = await client.getPayout({ payoutId: payout.id }); + +// Update metadata +await client.updatePayout({ payoutId: payout.id, trackingId: 'payout-001-v2' }); +``` + +## Deployment Queue & Signatures + +```ts +import { QueueOperationStatus } from '@b2binpay/defi-sdk'; + +// Fetch pending/ready operations +const queue = await client.getDeploymentQueue({}); +const pending = queue.items.filter((op) => op.status === QueueOperationStatus.Pending); + +// Submit a signature (raw ECDSA hex — packed automatically by the SDK) +await client.submitOperationSignature({ + operationId: operation.executeOperationId, + signature: rawSignature, + signerAddress: account.address, // required for v1.1.0 contracts +}); +``` + +> **Signature packing:** The SDK automatically packs signatures to the format expected by the contract version. For v1.1.0 contracts, `signerAddress` is required. Pass the raw ECDSA hex from `signTypedData` — do not pre-pack. + +## Transactions + +```ts +import { TransactionOperationType } from '@b2binpay/defi-sdk'; + +const txList = await client.getTransactions({ + operationTypes: [TransactionOperationType.Payout], + pageSize: 20, +}); + +const tx = await client.getTransaction({ transactionId: txList.items[0].id }); +console.log('Claimed:', tx.isClaimed); +``` + +## Claims + +```ts +// List claimable deposits +const claims = await client.getClaims({ pageSize: 50 }); + +// Currencies with claimable balances +const claimable = await client.getClaimableCurrencies(); +``` + +Broadcasting claim transactions is done off-chain through `MultisigBlockchainClient.buildClaimCalldata` (EVM) or `TronMultisigBlockchainClient.buildClaimTransaction` (TRON). See [`examples/claim-deposits.ts`](../examples/claim-deposits.ts) and [`examples/tron-claim-deposits.ts`](../examples/tron-claim-deposits.ts). ## Error Handling -All generated API methods throw `ResponseError` when the server responds with non-2xx status codes. Catch these errors to read the JSON body for additional context, as demonstrated in `examples/get-account-info.ts`. -## Validation Helpers -Use `validateAddress({ address, networkChainId, currency, assets })` from `src/utils/validation` (re-exported via `@b2binpay/defi-sdk`) before submitting payouts or invoices. The helper enforces checksum address formatting, verifies currency/network combinations, and ensures the currency is part of the provided asset list, returning `{ isValid, errors, normalizedAddress }`. +All API methods throw `ResponseError` on non-2xx responses. Parse the response body for details: + +```ts +import { ResponseError } from '@b2binpay/defi-sdk'; + +try { + await client.createPayout({ ... }); +} catch (err) { + if (err instanceof ResponseError) { + const body = await err.response.json(); + console.error('API error:', body); + } + throw err; +} +``` diff --git a/docs/contributing.md b/docs/contributing.md index 7cdbc87..e98687a 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,33 +1,63 @@ # Contributing Guide ## Prerequisites -- Node `^22.16.0` and npm `^10.9.2`. -- Access to the OpenAPI specification for regenerating `generated-contracts/`. -- Wallet tooling capable of signing messages for integration testing. + +- Node.js `^22.16.0` and npm `^10.9.2` +- Access to the OpenAPI specification for regenerating `generated-contracts/` +- A wallet private key and API credentials for running integration examples ## Project Commands + - `npm install`: Install dependencies. -- `npm run generate:api`: Regenerate REST client from the remote OpenAPI spec. +- `npm run build`: Compile TypeScript to `dist/` using `tsconfig.build.json`. +- `npm test`: Run the test suite (`jest`). - `npm run lint`: Check and format code with Biome. +- `npm run lint:fix`: Auto-fix Biome issues. +- `npm run generate:api`: Regenerate REST client from the remote OpenAPI spec. +- `npm run generate:api:local`: Same as above but using `openapitools.local.json`. +- `npx tsc --noEmit`: Type-check the project without emitting files. - `npm run example:get-account-info`: Run the reference example (requires `.env`). -- `npx tsc --noEmit`: Type-check the project. + +## Running Examples + +Copy `.env.example` to `.env` and fill in the required values: + +```sh +cp .env.example .env +``` + +Required variables: `API_BASE_URL`, `API_KEY`, `CHAIN_ID`, `RPC_URL`, `WALLET_PRIVATE_KEY`. +See `.env.example` for the full list including optional TRON-specific variables. ## Workflow -1. Update or regenerate API contracts as needed. + +1. Update or regenerate API contracts as needed with `npm run generate:api`. 2. Implement changes inside `src/` (API layer or utilities). -3. Add or update documentation under `docs/`. -4. Update examples/tests to reflect new behaviour. -5. Run `npx tsc --noEmit` before opening a PR. +3. Add or update tests under `src/**/*.spec.ts`. +4. Update documentation under `docs/` and examples under `examples/`. +5. Run `npm run lint` and `npx tsc --noEmit` before opening a PR. ## Coding Guidelines -- Prefer TypeScript modules in `src/` with explicit named exports. -- Keep shared interfaces/types in dedicated files when used by multiple modules. + +- Use TypeScript strict mode; avoid `any` — use `unknown` with type guards. +- Do not use `as` casts to suppress type errors; fix the underlying type instead. +- Prefer named exports; keep shared types in dedicated files when used across modules. - Favour composition over inheritance; expose helper functions over classes unless stateful behaviour is required. - Limit comments to non-obvious logic and architectural decisions. +## Code Generation + +`generated-contracts/` is fully generated — never edit it manually. Regenerate when the OpenAPI spec changes: + +```sh +npm run generate:api +``` + ## Release Preparation + - Ensure `generated-contracts/` is up to date and committed. -- Bump the version in `package.json` (to be configured once publishing is in place). -- Attach release notes referencing relevant documentation updates. +- Verify all examples run against the target environment. +- Run `npm test`, `npm run lint`, and `npx tsc --noEmit`. +- Version is managed by CI — do not modify it manually in `package.json`. For architectural orientation review `docs/overview.md` first, then reference module-specific guides. diff --git a/docs/overview.md b/docs/overview.md index 7a42259..a42f96e 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -1,33 +1,86 @@ # SDK Overview -This SDK provides a single TypeScript entry point that combines REST API access with smart-contract helpers tailored to the B2BinPay DeFi stack. +`@b2binpay/defi-sdk` is a TypeScript package that combines REST API access with smart-contract helpers for the B2BinPay DeFi platform. It targets Node.js server-side usage where an application needs to manage payment flows through a non-custodial multisig wallet. -- The **API layer** lives under `src/api` and wraps the generated `AccountsApi` (and related REST modules) so consumers interact with concise methods like `getAccountBalanceSummary`. -- The **transaction utilities** under `src/utils/transactions` encapsulate `viem` logic for composing, signing, and (soon) decoding contract payloads. -- Shared contract interfaces live under `src/abi`, ensuring builders/decoders stay consistent with the deployed contracts. -- Documentation is collated in the `docs/` folder and is shipped with the npm package for discoverability. +## Architecture + +``` +@b2binpay/defi-sdk +├── src/api/ – Hand-written REST wrapper (DefiClient) +│ └── models/ – Typed interfaces and enums +├── src/blockchain/ – Chain-aware clients +│ ├── multisig-client.ts – MultisigBlockchainClient (EVM) +│ ├── tron-multisig-client.ts – TronMultisigBlockchainClient (TVM) +│ ├── get-chain.ts – Chain resolver utilities +│ └── tron-chains.ts – TRON chain configs (Mainnet, Shasta) +├── src/utils/ +│ ├── transactions/ – EIP-712 / TIP-712 builders and helpers +│ ├── validation.ts – EVM address validation +│ ├── tron-validation.ts – TRON address validation +│ └── tron-types.ts – Branded TronAddress type +└── generated-contracts/ – OpenAPI-generated DTOs and API classes +``` + +## Layers + +### API Layer (`src/api`) + +`DefiClient` wraps the generated OpenAPI client and exposes convenience methods grouped by domain: accounts, balances, currencies, invoices, payouts, claims, transactions, and the deployment queue. It handles: + +- Automatic `x-api-key` injection on every request +- Account resolution (API key → account → deployments) +- Chain selection caching (`selectChain`) so downstream calls omit explicit chain/deployment IDs +- ABI fetching and caching (`getContractAbi`) with optional disk persistence + +### Blockchain Layer (`src/blockchain`) + +Chain-aware helpers that bridge the API layer with on-chain operations: + +- **`MultisigBlockchainClient`** (EVM) — uses a viem `PublicClient` for RPC reads; builds EIP-712 typed data for signing, encodes `execute` transactions, and assembles claim calldata +- **`TronMultisigBlockchainClient`** (TVM) — uses TronWeb; builds TIP-712 typed data, encodes `execute` and `claim` transactions for TRON + +Both clients accept an `AbiCacheEntry` from `client.getContractAbi()` to support v1.0.0 and v1.1.0 signature packing formats. + +### Transaction Utilities (`src/utils/transactions`) + +Low-level helpers consumed by the blockchain clients but also exported directly: + +- **EIP-712** — `createExecuteTypedData`, `buildExecuteTypedMessage`, `fetchExecuteTypedDataDomain`, `signExecuteTypedData` +- **TIP-712** — `buildTronExecuteTypedData`, `fetchTronExecuteTypedDataDomain`, `prepareTronTypedDataForSigning` +- **Builders** — `buildExecuteOperationsTransaction` (EVM), `packSignatures`, `packTronSignatures` + +### Validation (`src/utils/validation`) + +`validateAddress` enforces address correctness before write operations — EVM checksum, TRON Base58Check, chain and currency compatibility. ## High-Level Workflow -1. Authenticate requests by instantiating `DefiClient` with your API key (sent automatically via `x-api-key`). -2. Interact with REST endpoints using the client’s convenience methods. -3. Build and sign contract transactions through the utility layer. -4. Decode on-chain data returned from contract calls with the same helper set (decoders WIP). - -## Supported Workflows -- **Authentication management** – every client instance binds to a sandbox or production base URL and injects the API key automatically. -- **Account & ledger data** – fetch account details, balances, deployment queues, invoices, payouts, and transactions with a single method call. -- **Chain selection** – use `selectChain(chainId)` to cache the deployment for a target network so subsequent invoice/payout/claim calls don’t need explicit deployment IDs. -- **Invoice lifecycle** – create, update, and cancel invoices with tracking IDs, callback URLs, and custom currency selections. -- **Payout lifecycle** – list payouts with filters, fetch payout details, patch metadata, and submit multisig signatures. -- **Claims management** – enumerate claimable deposits and trigger single/batch claim executions tied to signed transaction hashes. -- **Validation helpers** – `validateAddress` enforces address + network correctness before hitting write endpoints, reducing API errors. + +1. **Instantiate `DefiClient`** with `baseUrl` and `apiKey` +2. **Select a chain** with `selectChain(chainId)` — caches the deployment for the session +3. **Fetch the contract ABI** with `getContractAbi()` — cached in memory and optionally on disk +4. **Manage invoices and payouts** via `createInvoice`, `createPayout`, etc. +5. **Sign operations** — build EIP-712/TIP-712 typed data, sign with a wallet, submit via `submitOperationSignature` +6. **Execute on-chain** — build the `execute` transaction with `buildExecuteTransaction`, broadcast it +7. **Claim deposits** — build claim calldata with `buildClaimCalldata` or `buildClaimTransaction` (TRON), broadcast + +## Signature Packing + +The SDK auto-applies the correct packing format based on the contract version in the fetched ABI: + +- **v1.0.0** — raw ECDSA signatures, sorted and concatenated +- **v1.1.0** — binary format with explicit signer addresses: `[address:20][sigLen:2][sig:sigLen]` sorted by signer address and concatenated. ## Published Package -The publishable module exports: -- `DefiClient` and supporting types for API-key-based account flows. -- Transaction helper utilities (`transactions.buildExecuteOperationsTransaction`, `transactions.createExecuteTypedData`, `transactions.signExecuteTypedData`, etc.) under a dedicated namespace. -- Shared ABI exports (`abi.MULTI_SIG_WALLET_ABI`) for contract-aware integrations. -See `examples/queue-sign.ts` for a combined flow that authenticates, fetches the linked account, builds a payout execute payload, and signs it, `examples/queue-execute.ts` for broadcasting the execute transaction, and `examples/claim-deposits.ts` for on-chain claim calldata and broadcasting. +The npm package exports: + +- `DefiClient` and all supporting types +- `MultisigBlockchainClient` (EVM) +- `TronMultisigBlockchainClient` (TVM) +- `getEvmChainById`, `getTronChainById`, `getChainById` — chain resolver utilities +- `validateAddress` — address + network validator +- Transaction helpers under the `transactions` namespace +- `AbiProvider` and `AbiCacheEntry` — ABI fetching and caching +- Enums: `FiatCurrency`, `InvoiceStatus`, `PayoutStatus`, `QueueOperationType`, `QueueOperationStatus`, `TransactionOperationType`, and more -Refer to `docs/api-client.md` and `docs/transactions.md` for deep dives into each layer. +Refer to [`docs/api-client.md`](api-client.md) and [`docs/transactions.md`](transactions.md) for detailed reference. diff --git a/docs/transactions.md b/docs/transactions.md index dbf228f..69b6737 100644 --- a/docs/transactions.md +++ b/docs/transactions.md @@ -1,36 +1,233 @@ # Transaction Utilities -This SDK exposes a cohesive set of helpers under `src/utils/transactions` to standardise interactions with the B2BinPay smart contract ecosystem. +This document covers the blockchain interaction layer: EIP-712/TIP-712 typed-data helpers, transaction builders, signature packing, and the chain-aware client wrappers. -## Modules -- `builders/`: Functions that create transaction payloads for contract methods. Currently includes `buildExecuteOperationsTransaction`, which encodes a `MultiSigWallet.execute` call for one or more queued operations. -- `eip712/`: Helpers for building EIP-712 typed data (`createExecuteTypedData`, `buildExecuteTypedMessage`) and optional sign helpers. -- `blockchain/MultisigBlockchainClient`: RPC-aware helper that wraps `eip712` utilities, producing execute-typed data while keeping API interactions optional; also exposes `buildClaimCalldata` for claim transactions. -- ABI definitions required by these helpers are stored under `src/abi` to keep contract interfaces versioned alongside the SDK. +## MultisigBlockchainClient (EVM) -## Design Goals -- **Type safety**: Reuse the same DTOs/ABI typings across builders, signers, and decoders. -- **Deterministic encoding**: Ensure every canonical contract call has a single builder that validates inputs before encoding. -- **Composable flows**: Allow apps to compose API data + transaction payload generation without duplicating logic. -- **Test coverage**: Each helper will include contract-level test vectors and integration fixtures. +`MultisigBlockchainClient` (`src/blockchain/multisig-client.ts`) encapsulates EVM multisig operations using viem. +### Construction -- Use `buildExecuteOperationsTransaction` (via `transactions.builders` or `MultisigBlockchainClient.buildExecuteTransaction`) to encode on-chain `MultiSigWallet.execute` calls for one or many queue operations. -- Use `MultisigBlockchainClient.buildClaimCalldata` to assemble calldata for `claim`/`claimTo` when broadcasting claim transactions. -- See `examples/queue-sign.ts` for signing, `examples/queue-execute.ts` / `examples/queue-execute-batch.ts` for broadcasting execute transactions, and `examples/claim-deposits.ts` for claim calldata + broadcasting. +```ts +import { createPublicClient, http } from 'viem'; +import { MultisigBlockchainClient, getEvmChainById } from '@b2binpay/defi-sdk'; + +const chain = getEvmChainById(String(CHAIN_ID), process.env.RPC_URL!); +const publicClient = createPublicClient({ chain, transport: http(process.env.RPC_URL!) }); + +const contractAbi = await client.getContractAbi(); // from DefiClient + +const multisig = new MultisigBlockchainClient({ + chainId: String(CHAIN_ID), + publicClient, + contractAbi, +}); +``` + +### Methods + +#### `createExecuteTypedData(args)` + +Builds an EIP-712 typed-data payload for signing a pending multisig operation. + +```ts +const typedData = await multisig.createExecuteTypedData({ + contractAddress: deployment.contract as `0x${string}`, + operation, // QueueOperation from getDeploymentQueue() + domainOverride, // optional: skip on-chain domain fetch +}); + +const signature = await account.signTypedData(typedData); +``` + +#### `buildExecuteTransaction(params)` + +Encodes a `MultiSigWallet.execute()` call for one or more ready operations. + +```ts +const tx = multisig.buildExecuteTransaction({ + contractAddress: deployment.contract as `0x${string}`, + operations: [op1, op2], // one or more QueueOperations +}); +// tx: { to, data, chainId, value } +await walletClient.sendTransaction(tx); +``` + +#### `buildClaimCalldata(params)` + +Generates calldata for `claim(erc20, depositIds)` or `claimTo(erc20, depositIds, recipient)`. + +```ts +const calldata = multisig.buildClaimCalldata({ + erc20: currency.address as `0x${string}`, + depositAccountIds: claims.items.map((c) => c.invoiceNonce), + to: recipientAddress, // optional: uses contract default if omitted +}); +``` + +--- + +## TronMultisigBlockchainClient (TVM) + +`TronMultisigBlockchainClient` (`src/blockchain/tron-multisig-client.ts`) mirrors the EVM client for TRON chains. + +### Construction + +```ts +import TronWeb from 'tronweb'; +import { TronMultisigBlockchainClient } from '@b2binpay/defi-sdk'; + +const tronWeb = new TronWeb({ + fullHost: process.env.RPC_URL!, + privateKey: process.env.WALLET_PRIVATE_KEY, +}); + +const multisig = new TronMultisigBlockchainClient({ + chainId: String(CHAIN_ID), + tronWeb, + contractAbi, // from client.getContractAbi() + defaultFeeLimit: 150_000_000, // 150 TRX in SUN +}); +``` + +### Methods + +#### `createExecuteTypedData(args)` + +Builds a TIP-712 typed-data payload for signing. + +```ts +const typedData = await multisig.createExecuteTypedData({ + contractAddress: deployment.contract, // Tron base58 address + operation, +}); + +const signature = await tronWeb.trx.signMessageV2(typedData.message); +``` + +#### `buildExecuteTransaction(params)` + +Encodes a TRON `execute()` transaction. + +```ts +const tx = await multisig.buildExecuteTransaction({ + contractAddress: deployment.contract, + callerAddress: tronWeb.defaultAddress.base58, + operations: [readyOp], + feeLimit: 200_000_000, // optional override +}); +await tronWeb.trx.sendRawTransaction(tx.raw); +``` + +#### `buildClaimTransaction(params)` + +Encodes a TRON claim transaction. + +```ts +const tx = await multisig.buildClaimTransaction({ + contractAddress: deployment.contract, + callerAddress: tronWeb.defaultAddress.base58, + erc20: currency.address, + depositIds: claims.items.map((c) => c.invoiceNonce), +}); +await tronWeb.trx.sendRawTransaction(tx.raw); +``` + +--- + +## Chain Resolvers + +```ts +import { getEvmChainById, getTronChainById, getChainById } from '@b2binpay/defi-sdk'; + +// Returns a viem Chain object for known EVM chains; throws on unknown IDs +const chain = getEvmChainById('11155111', process.env.RPC_URL); + +// Returns a TronChainConfig (fullHost, chainId, etc.) +const tronChain = getTronChainById('728126428'); + +// Universal resolver — returns viem Chain or TronChainConfig +const unknown = getChainById(String(chainId)); +``` + +--- + +## Low-Level Transaction Utilities + +The utilities in `src/utils/transactions` are re-exported from the package under the `transactions` namespace. Use them if you need finer control than the blockchain clients provide. -### Signing Queue Operations -When a payout is created, the backend enqueues a multisig operation. The `executeOperationId` exposed by the queue can be signed locally using: +### EIP-712 (EVM) ```ts +import { transactions } from '@b2binpay/defi-sdk'; + +// Full pipeline: fetch domain from contract, build message, return typed data const typedData = await transactions.createExecuteTypedData({ contractAddress, operation, publicClient, }); -const signature = await account.signTypedData(typedData); +// Build a typed message directly (no RPC call) +const message = transactions.buildExecuteTypedMessage({ calls, nonce }); + +// Sign with a viem LocalAccount +const sig = await transactions.signExecuteTypedData({ account, typedData }); +``` + +### TIP-712 (TVM) + +```ts +import { transactions } from '@b2binpay/defi-sdk'; + +const typedData = transactions.buildTronExecuteTypedData({ + domain, + calls, + nonce, + contractVersion, +}); + +// Prepare for TronWeb signing (converts BigInt to string) +const signable = transactions.prepareTronTypedDataForSigning(typedData); +``` + +### Signature Packing + +Signatures are packed automatically by `submitOperationSignature`. If you need direct access: + +```ts +import { transactions } from '@b2binpay/defi-sdk'; + +// EVM +const packed = transactions.packSignatures([{ signer, signature }], contractVersion); + +// TVM +const packedTron = transactions.packTronSignatures([{ signer, signature }], contractVersion); +``` + +- **v1.0.0**: raw 65-byte ECDSA signatures sorted and concatenated +- **v1.1.0**: `[signer:20 bytes][sigLen:2 bytes uint16 BE][sig:sigLen bytes]` entries sorted by signer address and concatenated. + +--- + +## Signing Flow Summary + +``` +createPayout() + ↓ +getDeploymentQueue() — fetch pending operation + ↓ +createExecuteTypedData() — build EIP-712 / TIP-712 payload + ↓ +wallet.signTypedData() — sign off-chain + ↓ +submitOperationSignature() — submit to API (auto-packs signature) + ↓ +getDeploymentQueue() — poll until status = Ready + ↓ +buildExecuteTransaction() — encode on-chain call + ↓ +walletClient.sendTransaction() — broadcast ``` -Submit the resulting signature with `submitOperationSignature` on the `DefiClient` to record approval. If you prefer a -higher-level abstraction, instantiate `MultisigBlockchainClient` and call `createExecuteTypedData` directly. +See [`examples/evm-full-flow.ts`](../examples/evm-full-flow.ts) and [`examples/tron-full-flow.ts`](../examples/tron-full-flow.ts) for end-to-end runnable examples. diff --git a/examples/claim-deposits.ts b/examples/claim-deposits.ts index c2089fb..8a3d292 100644 --- a/examples/claim-deposits.ts +++ b/examples/claim-deposits.ts @@ -9,7 +9,7 @@ import 'dotenv/config'; import { type Address, createPublicClient, createWalletClient, http, zeroAddress } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { DefiClient, MultisigBlockchainClient } from '../src'; -import { getChainById } from '../src/blockchain/get-chain'; +import { getEvmChainById } from '../src/blockchain/get-chain'; import { normalizePrivateKey, parseChainId, requireEnvVars, runMain } from './utils'; const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'RPC_URL', 'WALLET_PRIVATE_KEY'] as const; @@ -48,7 +48,7 @@ runMain(async () => { const invoicesToClaim = claims.items.filter((item) => item.currency.id === currency.id); const depositAccountIds = invoicesToClaim.map((item) => item.invoiceNonce); - const chain = getChainById(chainId, rpcUrl); + const chain = getEvmChainById(chainId, rpcUrl); const publicClient = createPublicClient({ chain, transport: http(rpcUrl), @@ -60,9 +60,12 @@ runMain(async () => { account: wallet, transport: http(rpcUrl), }); + const contractAbi = await client.getContractAbi(); + const multisigClient = new MultisigBlockchainClient({ chainId, publicClient, + contractAbi, }); const erc20Address = currency.address ?? zeroAddress; diff --git a/examples/evm-full-flow.ts b/examples/evm-full-flow.ts new file mode 100644 index 0000000..b1e1a58 --- /dev/null +++ b/examples/evm-full-flow.ts @@ -0,0 +1,443 @@ +/** + * EVM full-flow example: + * Demonstrates the complete money lifecycle on an EVM chain using the DefiSDK. + * + * Steps: + * 1. Setup — authenticate, select chain, print initial balances + * 2. Invoice — create a native currency invoice and automatically send the deposit from the signer wallet + * 3. Deposit — poll transactions API until deposit appears, then wait for CONFIRMED status + * 4. Claim — build and broadcast claim tx, wait for confirmation + * 5. Payout — create a native currency payout back to a test address + * 6. Sign — build EIP-712 typed data and submit signature + * 7. Execute — wait for the operation to be ready, then broadcast execute tx + * 8. Summary — print final account balances + * + * Required environment variables: + * API_BASE_URL — DeFi API base URL + * API_KEY — API key + * CHAIN_ID — numeric EVM chain ID + * RPC_URL — JSON-RPC endpoint for the chain + * WALLET_PRIVATE_KEY — hex private key of the signer wallet (32 bytes) + * PAYOUT_RECIPIENT — address to receive the payout + * + * Optional: + * POLL_INTERVAL_MS — polling interval in ms (default: 5000) + * POLL_TIMEOUT_MS — maximum polling time in ms (default: 300000 / 5 min) + */ +import 'dotenv/config'; +import { + type Address, + createPublicClient, + createWalletClient, + http, + type PublicClient, + parseEther, + zeroAddress, +} from 'viem'; +import { privateKeyToAccount } from 'viem/accounts'; +import { + AssetSortField, + AssetSortOrder, + type ClaimItem, + DefiClient, + FiatCurrency, + MultisigBlockchainClient, + type QueueOperation, + type Transaction, + TransactionOperationType, + TransactionStatus, +} from '../src'; +import { getEvmChainById } from '../src/blockchain/get-chain'; +import { normalizePrivateKey, parseChainId, requireEnvVars, runMain } from './utils'; + +const REQUIRED_ENV = [ + 'API_BASE_URL', + 'API_KEY', + 'CHAIN_ID', + 'RPC_URL', + 'WALLET_PRIVATE_KEY', + 'PAYOUT_RECIPIENT', +] as const; + +const PAYOUT_AMOUNT = '0.00005'; +const INVOICE_AMOUNT = '0.0001'; +const BASE_CURRENCY = FiatCurrency.Usd; +const TX_RECEIPT_TIMEOUT_MS = 360_000; +const TX_RECEIPT_POLL_MS = 3_000; + +runMain(async () => { + const env = requireEnvVars(REQUIRED_ENV); + const chainId = parseChainId(env.CHAIN_ID); + const rpcUrl = env.RPC_URL; + const pollInterval = Number(process.env.POLL_INTERVAL_MS ?? '5000'); + const pollTimeout = Number(process.env.POLL_TIMEOUT_MS ?? '300000'); + + // ─── Step 1: Setup ─────────────────────────────────────────────────────────── + console.log('\n═══ Step 1: Setup ═══'); + + const signer = privateKeyToAccount(normalizePrivateKey(env.WALLET_PRIVATE_KEY)); + console.log('Signer address:', signer.address); + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + const accountDetails = await client.getAccount(); + console.log('Account:', accountDetails.account.name, `(${accountDetails.account.id})`); + console.log('Contract:', accountDetails.account.contract); + + await client.selectChain(chainId); + console.log('Chain ID:', chainId); + + const chain = getEvmChainById(chainId, rpcUrl); + const publicClient = createPublicClient({ chain, transport: http(rpcUrl) }); + const walletClient = createWalletClient({ chain, account: signer, transport: http(rpcUrl) }); + const contractAbi = await client.getContractAbi(); + const multisigClient = new MultisigBlockchainClient({ chainId, publicClient, contractAbi }); + + const chainIdNumber = Number.parseInt(chainId, 10); + const initialBalances = await client.getAssetBalances({ + chainId, + baseCurrency: BASE_CURRENCY, + sortBy: AssetSortField.Balance, + sortOrder: AssetSortOrder.Desc, + pageSize: 20, + }); + + const nonZeroInitial = initialBalances.items.filter((b) => Number(b.balance) > 0); + if (nonZeroInitial.length > 0) { + console.log('Initial balances:'); + console.table(nonZeroInitial.map((b) => ({ symbol: b.currency.symbol, balance: b.balance }))); + } else { + console.log('Initial balances: all zero.'); + } + + const summary = await client.getAccountBalanceSummary({ chainId: chainIdNumber, baseCurrency: BASE_CURRENCY }); + console.log('Balance summary (USD):'); + console.table({ + total: summary.totalBalance, + uncollected: summary.uncollectedBalance, + uncollectedInvoices: summary.uncollectedInvoices, + }); + + // ─── Step 2: Invoice ───────────────────────────────────────────────────────── + console.log('\n═══ Step 2: Create invoice ═══'); + + const nativeCurrency = await client.getNativeCurrency(chainId); + console.log(`Native currency: ${nativeCurrency.symbol} (${nativeCurrency.id})`); + + const trackingId = `EVM-FULL-FLOW-${Date.now()}`; + + const invoice = await client.createInvoice({ + requestedAmount: INVOICE_AMOUNT, + trackingId, + callbackUrl: null, + paymentPageButtonUrl: null, + paymentPageButtonText: null, + currencyIds: [nativeCurrency.id], + }); + + console.log('Created invoice:'); + console.table({ + id: invoice.id, + trackingId: invoice.trackingId, + status: invoice.status, + amount: invoice.requestedAmount ?? 'open', + address: invoice.invoiceAddress, + paymentPageUrl: invoice.paymentPageUrl, + }); + + console.log(`\nSending ${INVOICE_AMOUNT} ${nativeCurrency.symbol} to invoice address ${invoice.invoiceAddress}...`); + const depositTxHash = await walletClient.sendTransaction({ + to: invoice.invoiceAddress as Address, + value: parseEther(INVOICE_AMOUNT), + }); + console.log('Deposit tx broadcasted:', depositTxHash); + const depositReceipt = await waitForReceipt(publicClient, depositTxHash); + console.log('Deposit tx included in block:', depositReceipt.blockNumber.toString()); + + // ─── Step 3: Wait for deposit ───────────────────────────────────────────────── + console.log('\n═══ Step 3: Waiting for deposit ═══'); + + const confirmedTx = await waitForTxConfirmation( + client, + depositTxHash, + TransactionOperationType.Invoice, + pollInterval, + pollTimeout, + ); + + console.log('Deposit confirmed:'); + console.table({ + txHash: confirmedTx.txHash, + status: confirmedTx.status, + confirmations: confirmedTx.confirmations, + confirmedAt: confirmedTx.confirmedAt, + canClaim: confirmedTx.canClaim, + }); + + // Fetch the corresponding claimable items for the claim step + const claimsResult = await client.getClaims({ invoiceId: invoice.id, pageSize: 50 }); + const claimItems: ClaimItem[] = claimsResult.items; + + if (claimItems.length === 0) { + throw new Error(`No claimable items found for invoice ${invoice.id} after transaction was confirmed.`); + } + + // ─── Step 4: Claim ──────────────────────────────────────────────────────────── + console.log('\n═══ Step 4: Claim ═══'); + + // Group by currency and claim each currency in one transaction + const currencyGroups = new Map(); + for (const item of claimItems) { + const key = item.currency.id; + const group = currencyGroups.get(key) ?? []; + group.push(item); + currencyGroups.set(key, group); + } + + for (const [, items] of currencyGroups) { + const currency = items[0].currency; + const depositAccountIds = items.map((item) => item.invoiceNonce); + const erc20Address = (currency.address ?? zeroAddress) as Address; + + const claimCalldata = multisigClient.buildClaimCalldata({ erc20: erc20Address, depositAccountIds }); + + console.log(`Claiming ${currency.symbol} for ${items.length} invoice(s)...`); + + const claimTxHash = await walletClient.sendTransaction({ + to: accountDetails.account.contract as Address, + account: signer, + data: claimCalldata, + value: 0n, + }); + + console.log('Claim tx broadcasted:', claimTxHash); + + const claimReceipt = await waitForReceipt(publicClient, claimTxHash); + console.log('Claim included in block:', claimReceipt.blockNumber.toString()); + + console.log('Waiting for claim transaction confirmation via API...'); + const confirmedClaim = await waitForTxConfirmation( + client, + claimTxHash, + TransactionOperationType.Claim, + pollInterval, + pollTimeout, + ); + console.log(`Claim confirmed: ${confirmedClaim.confirmations} confirmations`); + } + + // ─── Step 5: Payout ─────────────────────────────────────────────────────────── + console.log('\n═══ Step 5: Create payout ═══'); + + const payout = await client.createPayout({ + currencyId: nativeCurrency.id, + amount: PAYOUT_AMOUNT, + recipient: env.PAYOUT_RECIPIENT, + trackingId: `PAYOUT-${trackingId}`, + }); + + console.log('Payout created:'); + console.table({ + id: payout.id, + status: payout.status, + amount: `${payout.amount} ${payout.currency.symbol}`, + recipient: payout.toAddress, + }); + + // Find the associated queue operation + const payoutOperation = await poll( + 'payout queue operation', + async () => { + const queue = await client.getDeploymentQueue({ pageSize: 100 }); + const op = queue.items.find((item) => item.operationType === 'PAYOUT' && item.payload?.payoutId === payout.id); + return op ?? null; + }, + pollInterval, + pollTimeout, + ); + + console.log('Queue operation:'); + console.table({ + id: payoutOperation.id, + nonce: payoutOperation.nonce, + status: payoutOperation.status, + signaturesCollected: payoutOperation.signaturesCollected, + signaturesRequired: payoutOperation.signaturesRequired, + }); + + // ─── Step 6: Sign ───────────────────────────────────────────────────────────── + console.log('\n═══ Step 6: Sign ═══'); + + const typedData = await multisigClient.createExecuteTypedData({ + contractAddress: accountDetails.account.contract as Address, + operation: payoutOperation, + }); + + const signature = await signer.signTypedData(typedData); + console.log('Signature:', `${signature.slice(0, 20)}...`); + + const signatureResponse = await client.submitOperationSignature({ + operationId: payoutOperation.id, + signature, + signerAddress: signer.address, + }); + + console.log('Signature submitted:'); + console.table({ + operationId: signatureResponse.operationId, + signaturesCollected: signatureResponse.signaturesCollected, + signaturesRequired: signatureResponse.signaturesRequired, + }); + + // ─── Step 7: Execute ────────────────────────────────────────────────────────── + console.log('\n═══ Step 7: Execute ═══'); + + // Wait until our payout operation is ready (signaturesCollected >= signaturesRequired), + // then collect all consecutive ready operations from nextExecutableNonce and execute them + // in a single batch tx. This handles the case where previous nonces are blocking our operation. + const operationsToExecute = await poll( + 'executable operation', + async () => { + const queue = await client.getDeploymentQueue({ statuses: ['READY'], pageSize: 100 }); + + const payoutReady = queue.items.some((item) => item.id === payoutOperation.id); + if (!payoutReady) return null; + + const batch: QueueOperation[] = []; + let currentNonce = Number(queue.nextExecutableNonce); + for (const item of queue.items) { + if (item.nonce !== currentNonce.toString()) break; + if (item.signaturesCollected < item.signaturesRequired) break; + batch.push(item); + currentNonce++; + } + + const includesOurOp = batch.some((item) => item.id === payoutOperation.id); + return includesOurOp ? batch : null; + }, + pollInterval, + pollTimeout, + ); + + console.log(`Executing ${operationsToExecute.length} operation(s) in batch:`); + console.table(operationsToExecute.map((op) => ({ id: op.id, nonce: op.nonce, type: op.operationType }))); + + const executeTx = multisigClient.buildExecuteTransaction({ + contractAddress: accountDetails.account.contract, + operations: operationsToExecute, + }); + + const executeTxHash = await walletClient.sendTransaction({ + to: executeTx.to, + account: signer, + data: executeTx.data, + value: executeTx.value ?? 0n, + }); + + console.log('Execute tx broadcasted:', executeTxHash); + + const executeReceipt = await waitForReceipt(publicClient, executeTxHash); + console.log('Execute included in block:', executeReceipt.blockNumber.toString()); + + console.log('Waiting for payout transaction confirmation via API...'); + const confirmedPayout = await waitForTxConfirmation( + client, + executeTxHash, + TransactionOperationType.Payout, + pollInterval, + pollTimeout, + ); + console.log(`Payout confirmed: ${confirmedPayout.confirmations} confirmations`); + + // ─── Step 8: Summary ────────────────────────────────────────────────────────── + console.log('\n═══ Step 8: Final balances ═══'); + + const finalBalances = await client.getAssetBalances({ + chainId, + baseCurrency: BASE_CURRENCY, + sortBy: AssetSortField.Balance, + sortOrder: AssetSortOrder.Desc, + pageSize: 20, + }); + + const nonZeroFinal = finalBalances.items.filter((b) => Number(b.balance) > 0); + if (nonZeroFinal.length > 0) { + console.table(nonZeroFinal.map((b) => ({ symbol: b.currency.symbol, balance: b.balance }))); + } else { + console.log('All balances are zero after the flow.'); + } + + const finalSummary = await client.getAccountBalanceSummary({ chainId: chainIdNumber, baseCurrency: BASE_CURRENCY }); + console.log('Final balance summary (USD):'); + console.table({ + total: finalSummary.totalBalance, + uncollected: finalSummary.uncollectedBalance, + uncollectedInvoices: finalSummary.uncollectedInvoices, + }); + + console.log('\n✓ Full EVM flow completed successfully.'); +}); + +async function waitForReceipt(client: PublicClient, hash: `0x${string}`) { + const deadline = Date.now() + TX_RECEIPT_TIMEOUT_MS; + + while (Date.now() < deadline) { + try { + const receipt = await client.getTransactionReceipt({ hash }); + return receipt; + } catch { + await new Promise((resolve) => setTimeout(resolve, TX_RECEIPT_POLL_MS)); + } + } + + throw new Error(`Transaction receipt for ${hash} not found after ${TX_RECEIPT_TIMEOUT_MS / 1000}s`); +} + +async function waitForTxConfirmation( + apiClient: DefiClient, + txHash: string, + operationType: TransactionOperationType, + pollIntervalMs: number, + pollTimeoutMs: number, +): Promise { + const tx = await poll( + `${operationType} transaction`, + async () => { + const result = await apiClient.getTransactions({ operationTypes: [operationType], pageSize: 50 }); + return result.items.find((item) => item.txHash === txHash) ?? null; + }, + pollIntervalMs, + pollTimeoutMs, + ); + + if (tx.status === TransactionStatus.Confirmed) return tx; + + return poll( + `${operationType} confirmation`, + async () => { + const result = await apiClient.getTransactions({ operationTypes: [operationType], pageSize: 50 }); + const found = result.items.find((item) => item.id === tx.id); + if (!found) return null; + console.log(` confirmations: ${found.confirmations}, status: ${found.status}`); + return found.status === TransactionStatus.Confirmed ? found : null; + }, + pollIntervalMs, + pollTimeoutMs, + ); +} + +async function poll(label: string, fn: () => Promise, intervalMs: number, timeoutMs: number): Promise { + const deadline = Date.now() + timeoutMs; + + while (Date.now() < deadline) { + const result = await fn(); + if (result !== null) { + return result; + } + + const remaining = Math.round((deadline - Date.now()) / 1000); + console.log(`[${label}] not ready — retrying in ${intervalMs / 1000}s (${remaining}s remaining)...`); + await new Promise((resolve) => setTimeout(resolve, intervalMs)); + } + + throw new Error(`[${label}] timed out after ${timeoutMs / 1000}s`); +} diff --git a/examples/queue-execute-batch.ts b/examples/queue-execute-batch.ts index 61b3169..ee3a194 100644 --- a/examples/queue-execute-batch.ts +++ b/examples/queue-execute-batch.ts @@ -8,7 +8,7 @@ import 'dotenv/config'; import { createPublicClient, createWalletClient, http } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { DefiClient, MultisigBlockchainClient, type QueueOperation } from '../src'; -import { getChainById } from '../src/blockchain/get-chain'; +import { getEvmChainById } from '../src/blockchain/get-chain'; import { normalizePrivateKey, parseChainId, requireEnvVars, runMain } from './utils'; const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'RPC_URL', 'WALLET_PRIVATE_KEY'] as const; @@ -53,7 +53,7 @@ runMain(async () => { })), ); - const chain = getChainById(chainId, rpcUrl); + const chain = getEvmChainById(chainId, rpcUrl); const publicClient = createPublicClient({ chain, transport: http(rpcUrl), @@ -66,9 +66,12 @@ runMain(async () => { transport: http(rpcUrl), }); + const contractAbi = await client.getContractAbi(); + const multisigClient = new MultisigBlockchainClient({ chainId, publicClient, + contractAbi, }); const transaction = multisigClient.buildExecuteTransaction({ diff --git a/examples/queue-execute.ts b/examples/queue-execute.ts index 1b2c4e5..c67b4e9 100644 --- a/examples/queue-execute.ts +++ b/examples/queue-execute.ts @@ -8,7 +8,7 @@ import 'dotenv/config'; import { createPublicClient, createWalletClient, http } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { DefiClient, MultisigBlockchainClient } from '../src'; -import { getChainById } from '../src/blockchain/get-chain'; +import { getEvmChainById } from '../src/blockchain/get-chain'; import { normalizePrivateKey, parseChainId, requireEnvVars, runMain } from './utils'; const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'RPC_URL', 'WALLET_PRIVATE_KEY'] as const; @@ -29,7 +29,7 @@ runMain(async () => { throw new Error('No executable operations found in the queue.'); } - const chain = getChainById(chainId, rpcUrl); + const chain = getEvmChainById(chainId, rpcUrl); const publicClient = createPublicClient({ chain, transport: http(rpcUrl), @@ -42,9 +42,12 @@ runMain(async () => { transport: http(rpcUrl), }); + const contractAbi = await client.getContractAbi(); + const multisigClient = new MultisigBlockchainClient({ chainId, publicClient, + contractAbi, }); const transaction = multisigClient.buildExecuteTransaction({ diff --git a/examples/queue-sign.ts b/examples/queue-sign.ts index d0a6e07..86490b3 100644 --- a/examples/queue-sign.ts +++ b/examples/queue-sign.ts @@ -8,7 +8,7 @@ import 'dotenv/config'; import { type Address, createPublicClient, http } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { DefiClient, MultisigBlockchainClient } from '../src'; -import { getChainById } from '../src/blockchain/get-chain'; +import { getEvmChainById } from '../src/blockchain/get-chain'; import { normalizePrivateKey, parseChainId, requireEnvVars, runMain } from './utils'; const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'RPC_URL', 'WALLET_PRIVATE_KEY'] as const; @@ -45,13 +45,16 @@ runMain(async () => { }); const publicClient = createPublicClient({ - chain: getChainById(chainId, env.RPC_URL), + chain: getEvmChainById(chainId, env.RPC_URL), transport: http(env.RPC_URL), }); + const contractAbi = await client.getContractAbi(); + const multisigClient = new MultisigBlockchainClient({ publicClient, chainId, + contractAbi, }); const typedData = await multisigClient.createExecuteTypedData({ @@ -64,6 +67,7 @@ runMain(async () => { const signatureResponse = await client.submitOperationSignature({ operationId: operation.id, signature, + signerAddress: signer.address, }); console.log('Submitted signature:'); diff --git a/examples/tron-claim-deposits.ts b/examples/tron-claim-deposits.ts new file mode 100644 index 0000000..40ad6ac --- /dev/null +++ b/examples/tron-claim-deposits.ts @@ -0,0 +1,82 @@ +/** + * Tron: Claim deposits use case: + * - Authenticate via API key and select a Tron chain. + * - List claimable deposits on the Tron network. + * - Build a claim transaction using TronMultisigBlockchainClient. + * - Sign and broadcast via TronWeb. + */ +import 'dotenv/config'; +import { TronWeb } from 'tronweb'; +import { DefiClient, TRON_ZERO_ADDRESS, type TronAddress, TronMultisigBlockchainClient } from '../src'; +import { DEFAULT_FEE_LIMIT, parseChainId, requireEnvVars, runMain } from './utils'; + +const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'RPC_URL', 'WALLET_PRIVATE_KEY'] as const; + +runMain(async () => { + const env = requireEnvVars(requiredEnv); + const chainId = parseChainId(env.CHAIN_ID); + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + const accountDetails = await client.getAccount(); + await client.selectChain(chainId); + + const claims = await client.getClaims({ + chainId, + currencyIds: process.env.CLAIM_CURRENCY_ID ? [process.env.CLAIM_CURRENCY_ID] : undefined, + invoiceId: process.env.CLAIM_INVOICE_ID, + pageSize: Number(process.env.CLAIM_PAGE_SIZE ?? '50'), + }); + + if (claims.items.length === 0) { + throw new Error('No claimable deposits found on Tron.'); + } + + console.log('Claimable Tron deposits:'); + console.table( + claims.items.map((item) => ({ + invoiceId: item.invoiceId, + currency: item.currency.symbol, + amount: item.amount, + })), + ); + + const currency = claims.items[0].currency; + const invoicesToClaim = claims.items.filter((item) => item.currency.id === currency.id); + const depositIds = invoicesToClaim.map((item) => item.invoiceNonce); + + const tronWeb = new TronWeb({ + fullHost: env.RPC_URL, + privateKey: env.WALLET_PRIVATE_KEY, + }); + + const contractAbi = await client.getContractAbi(); + + const tronClient = new TronMultisigBlockchainClient({ + chainId, + tronWeb, + contractAbi, + defaultFeeLimit: DEFAULT_FEE_LIMIT, + }); + + const contractAddress = accountDetails.account.contract as TronAddress; + const erc20Address = (currency.address ?? TRON_ZERO_ADDRESS) as TronAddress; + + const callerAddress = TronWeb.address.fromPrivateKey(env.WALLET_PRIVATE_KEY); + if (!callerAddress) { + throw new Error('Failed to derive Tron address from private key.'); + } + + const claimTx = await tronClient.buildClaimTransaction({ + contractAddress, + callerAddress: callerAddress as TronAddress, + erc20: erc20Address, + depositIds, + }); + + console.log(`Claiming deposits in ${currency.symbol} for ${invoicesToClaim.length} invoices...`); + + const signedTx = await tronWeb.trx.sign(claimTx.raw as Parameters[0]); + const result = await tronWeb.trx.sendRawTransaction(signedTx as Parameters[0]); + + console.log('Claim transaction broadcasted:', result.txid); +}); diff --git a/examples/tron-create-invoice.ts b/examples/tron-create-invoice.ts new file mode 100644 index 0000000..db8dfba --- /dev/null +++ b/examples/tron-create-invoice.ts @@ -0,0 +1,41 @@ +/** + * Tron: Create invoice use case: + * - Authenticate via API key and select a Tron chain/deployment. + * - Find TRC-20 currency by symbol scoped to the Tron chain. + * - Create an invoice with requested amount and tracking ID. + */ +import 'dotenv/config'; +import { DefiClient } from '../src'; +import { parseChainId, requireEnvVars, runMain } from './utils'; + +const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID'] as const; + +runMain(async () => { + const env = requireEnvVars(requiredEnv); + const chainId = parseChainId(env.CHAIN_ID); + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + await client.selectChain(chainId); + + const currency = await client.findCurrencyBySymbol({ symbol: 'USDT' }); + + const invoice = await client.createInvoice({ + requestedAmount: '100.56', + trackingId: `TRON-EXAMPLE-${Date.now()}`, + callbackUrl: null, + paymentPageButtonUrl: null, + paymentPageButtonText: null, + currencyIds: [currency.id], + }); + + console.log('Created Tron invoice:'); + console.table({ + id: invoice.id, + currencies: invoice.availableCurrencies.map((c) => c.symbol).join(', '), + amount: invoice.requestedAmount ?? 'N/A', + status: invoice.status, + trackingId: invoice.trackingId, + paymentPageUrl: invoice.paymentPageUrl, + invoiceAddress: invoice.invoiceAddress, + }); +}); diff --git a/examples/tron-create-payout.ts b/examples/tron-create-payout.ts new file mode 100644 index 0000000..cef0eee --- /dev/null +++ b/examples/tron-create-payout.ts @@ -0,0 +1,53 @@ +/** + * Tron: Create payout use case: + * - Authenticate via API key and select a Tron chain/deployment. + * - Resolve TRC-20 currency and create a payout to a Tron address. + * - Show associated queue operation for follow-up signing/execution. + */ +import 'dotenv/config'; +import { DefiClient } from '../src'; +import { parseChainId, requireEnvVars, runMain } from './utils'; + +const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'PAYOUT_RECIPIENT'] as const; + +const PAYOUT_CURRENCY_SYMBOL = 'USDT'; +const PAYOUT_AMOUNT = '1.00'; + +runMain(async () => { + const env = requireEnvVars(requiredEnv); + const chainId = parseChainId(env.CHAIN_ID); + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + + const deployment = await client.selectChain(chainId); + console.log('Using Tron deployment:', deployment.deploymentId); + + const currency = await client.findCurrencyBySymbol({ symbol: PAYOUT_CURRENCY_SYMBOL }); + + const payout = await client.createPayout({ + currencyId: currency.id, + amount: PAYOUT_AMOUNT, + recipient: env.PAYOUT_RECIPIENT, + callbackUrl: undefined, + trackingId: undefined, + }); + + const payoutDetails = await client.getPayout({ payoutId: payout.id }); + + console.log('Tron payout details:'); + console.table({ + id: payoutDetails.id, + status: payoutDetails.status, + amount: payoutDetails.amount, + currency: payoutDetails.currency.symbol, + queueOperationId: payoutDetails.queueOperationId, + }); + + const queue = await client.getDeploymentQueue({ pageSize: 100 }); + const operation = queue.items.find((item) => item.operationType === 'PAYOUT' && item.payload?.payoutId === payout.id); + if (!operation) { + throw new Error(`Payout operation for ${payout.id} not found in queue.`); + } + + console.log('Next step: sign operation', operation.id, 'and execute when ready.'); +}); diff --git a/examples/tron-full-flow.ts b/examples/tron-full-flow.ts new file mode 100644 index 0000000..e612242 --- /dev/null +++ b/examples/tron-full-flow.ts @@ -0,0 +1,456 @@ +/** + * Tron full-flow example: + * Demonstrates the complete money lifecycle on a Tron chain using the DefiSDK. + * + * Steps: + * 1. Setup — authenticate, select chain, print initial balances + * 2. Invoice — create a native TRX invoice and send deposit via TronWeb + * 3. Deposit — poll transactions API until deposit appears, then wait for CONFIRMED status + * 4. Claim — build and broadcast claim tx, wait for confirmation + * 5. Payout — create a USDT payout to a test address + * 6. Sign — build TIP-712 typed data and submit signature + * 7. Execute — wait for the operation to be ready, then broadcast execute tx + * 8. Summary — print final account balances + * + * Required environment variables: + * API_BASE_URL — DeFi API base URL + * API_KEY — API key + * CHAIN_ID — Tron chain ID (e.g. 728126428 for mainnet, 2494104990 for Shasta) + * RPC_URL — TronWeb full host URL + * WALLET_PRIVATE_KEY — hex private key of the signer wallet + * PAYOUT_RECIPIENT — Tron address to receive the payout + * + * Optional: + * POLL_INTERVAL_MS — polling interval in ms (default: 5000) + * POLL_TIMEOUT_MS — maximum polling time in ms (default: 300000 / 5 min) + * PAYOUT_CURRENCY — payout currency symbol (default: USDT) + */ +import 'dotenv/config'; +import { TronWeb } from 'tronweb'; +import { + AssetSortField, + AssetSortOrder, + type ClaimItem, + DefiClient, + FiatCurrency, + type QueueOperation, + TRON_ZERO_ADDRESS, + type Transaction, + TransactionOperationType, + TransactionStatus, + type TronAddress, + TronMultisigBlockchainClient, + transactions, +} from '../src'; +import { DEFAULT_FEE_LIMIT, parseChainId, requireEnvVars, runMain } from './utils'; + +const REQUIRED_ENV = [ + 'API_BASE_URL', + 'API_KEY', + 'CHAIN_ID', + 'RPC_URL', + 'WALLET_PRIVATE_KEY', + 'PAYOUT_RECIPIENT', +] as const; + +const INVOICE_AMOUNT = '1'; +const PAYOUT_AMOUNT = '1.00'; +const BASE_CURRENCY = FiatCurrency.Usd; +const TX_RECEIPT_TIMEOUT_MS = 120_000; +const TX_RECEIPT_POLL_MS = 3_000; +const TRON_SUN_PER_TRX = 1_000_000; + +runMain(async () => { + const env = requireEnvVars(REQUIRED_ENV); + const chainId = parseChainId(env.CHAIN_ID); + const pollInterval = Number(process.env.POLL_INTERVAL_MS ?? '5000'); + const pollTimeout = Number(process.env.POLL_TIMEOUT_MS ?? '300000'); + const payoutCurrencySymbol = process.env.PAYOUT_CURRENCY ?? 'USDT'; + + // ─── Step 1: Setup ─────────────────────────────────────────────────────────── + console.log('\n═══ Step 1: Setup ═══'); + + const tronWeb = new TronWeb({ + fullHost: env.RPC_URL, + privateKey: env.WALLET_PRIVATE_KEY, + }); + + const signerAddress = TronWeb.address.fromPrivateKey(env.WALLET_PRIVATE_KEY); + if (!signerAddress) { + throw new Error('Failed to derive Tron address from private key.'); + } + console.log('Signer address:', signerAddress); + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + const accountDetails = await client.getAccount(); + console.log('Account:', accountDetails.account.name, `(${accountDetails.account.id})`); + console.log('Contract:', accountDetails.account.contract); + + await client.selectChain(chainId); + console.log('Chain ID:', chainId); + + const contractAbi = await client.getContractAbi(); + const tronClient = new TronMultisigBlockchainClient({ + chainId, + tronWeb, + contractAbi, + defaultFeeLimit: DEFAULT_FEE_LIMIT, + }); + + const chainIdNumber = Number.parseInt(chainId, 10); + const initialBalances = await client.getAssetBalances({ + chainId, + baseCurrency: BASE_CURRENCY, + sortBy: AssetSortField.Balance, + sortOrder: AssetSortOrder.Desc, + pageSize: 20, + }); + + const nonZeroInitial = initialBalances.items.filter((b) => Number(b.balance) > 0); + if (nonZeroInitial.length > 0) { + console.log('Initial balances:'); + console.table(nonZeroInitial.map((b) => ({ symbol: b.currency.symbol, balance: b.balance }))); + } else { + console.log('Initial balances: all zero.'); + } + + const summary = await client.getAccountBalanceSummary({ chainId: chainIdNumber, baseCurrency: BASE_CURRENCY }); + console.log('Balance summary (USD):'); + console.table({ + total: summary.totalBalance, + uncollected: summary.uncollectedBalance, + uncollectedInvoices: summary.uncollectedInvoices, + }); + + // ─── Step 2: Invoice ───────────────────────────────────────────────────────── + console.log('\n═══ Step 2: Create invoice ═══'); + + const nativeCurrency = await client.getNativeCurrency(chainId); + console.log(`Native currency: ${nativeCurrency.symbol} (${nativeCurrency.id})`); + + const trackingId = `TRON-FULL-FLOW-${Date.now()}`; + + const invoice = await client.createInvoice({ + requestedAmount: INVOICE_AMOUNT, + trackingId, + callbackUrl: null, + paymentPageButtonUrl: null, + paymentPageButtonText: null, + currencyIds: [nativeCurrency.id], + }); + + console.log('Created invoice:'); + console.table({ + id: invoice.id, + trackingId: invoice.trackingId, + status: invoice.status, + amount: invoice.requestedAmount ?? 'open', + address: invoice.invoiceAddress, + paymentPageUrl: invoice.paymentPageUrl, + }); + + const depositAmountSun = Number(INVOICE_AMOUNT) * TRON_SUN_PER_TRX; + console.log(`\nSending ${INVOICE_AMOUNT} ${nativeCurrency.symbol} to invoice address ${invoice.invoiceAddress}...`); + const depositResult = await tronWeb.trx.sendTrx(invoice.invoiceAddress, depositAmountSun); + const depositTxId: string = depositResult.txid; + console.log('Deposit tx broadcasted:', depositTxId); + + await waitForTronReceipt(tronWeb, depositTxId); + console.log('Deposit tx confirmed on-chain.'); + + // ─── Step 3: Wait for deposit ───────────────────────────────────────────────── + console.log('\n═══ Step 3: Waiting for deposit ═══'); + + const confirmedTx = await waitForTxConfirmation( + client, + depositTxId, + TransactionOperationType.Invoice, + pollInterval, + pollTimeout, + ); + + console.log('Deposit confirmed:'); + console.table({ + txHash: confirmedTx.txHash, + status: confirmedTx.status, + confirmations: confirmedTx.confirmations, + confirmedAt: confirmedTx.confirmedAt, + canClaim: confirmedTx.canClaim, + }); + + const claimsResult = await client.getClaims({ invoiceId: invoice.id, pageSize: 50 }); + const claimItems: ClaimItem[] = claimsResult.items; + + if (claimItems.length === 0) { + throw new Error(`No claimable items found for invoice ${invoice.id} after transaction was confirmed.`); + } + + // ─── Step 4: Claim ──────────────────────────────────────────────────────────── + console.log('\n═══ Step 4: Claim ═══'); + + const contractAddress = accountDetails.account.contract as TronAddress; + const callerAddress = signerAddress as TronAddress; + + const currencyGroups = new Map(); + for (const item of claimItems) { + const key = item.currency.id; + const group = currencyGroups.get(key) ?? []; + group.push(item); + currencyGroups.set(key, group); + } + + for (const [, items] of currencyGroups) { + const currency = items[0].currency; + const depositIds = items.map((item) => item.invoiceNonce); + const erc20Address = (currency.address ?? TRON_ZERO_ADDRESS) as TronAddress; + + console.log(`Claiming ${currency.symbol} for ${items.length} invoice(s)...`); + + const claimTx = await tronClient.buildClaimTransaction({ + contractAddress, + callerAddress, + erc20: erc20Address, + depositIds, + }); + + const signedClaimTx = await tronWeb.trx.sign(claimTx.raw as Parameters[0]); + const claimResult = await tronWeb.trx.sendRawTransaction( + signedClaimTx as Parameters[0], + ); + + const claimTxId: string = claimResult.txid; + console.log('Claim tx broadcasted:', claimTxId); + + await waitForTronReceipt(tronWeb, claimTxId); + console.log('Claim tx confirmed on-chain.'); + + console.log('Waiting for claim transaction confirmation via API...'); + const confirmedClaim = await waitForTxConfirmation( + client, + claimTxId, + TransactionOperationType.Claim, + pollInterval, + pollTimeout, + ); + console.log(`Claim confirmed: ${confirmedClaim.confirmations} confirmations`); + } + + // ─── Step 5: Payout ─────────────────────────────────────────────────────────── + console.log('\n═══ Step 5: Create payout ═══'); + + const payoutCurrency = await client.findCurrencyBySymbol({ symbol: payoutCurrencySymbol }); + + const payout = await client.createPayout({ + currencyId: payoutCurrency.id, + amount: PAYOUT_AMOUNT, + recipient: env.PAYOUT_RECIPIENT, + trackingId: `PAYOUT-${trackingId}`, + }); + + console.log('Payout created:'); + console.table({ + id: payout.id, + status: payout.status, + amount: `${payout.amount} ${payout.currency.symbol}`, + recipient: payout.toAddress, + }); + + const payoutOperation = await poll( + 'payout queue operation', + async () => { + const queue = await client.getDeploymentQueue({ pageSize: 100 }); + const op = queue.items.find((item) => item.operationType === 'PAYOUT' && item.payload?.payoutId === payout.id); + return op ?? null; + }, + pollInterval, + pollTimeout, + ); + + console.log('Queue operation:'); + console.table({ + id: payoutOperation.id, + nonce: payoutOperation.nonce, + status: payoutOperation.status, + signaturesCollected: payoutOperation.signaturesCollected, + signaturesRequired: payoutOperation.signaturesRequired, + }); + + // ─── Step 6: Sign ───────────────────────────────────────────────────────────── + console.log('\n═══ Step 6: Sign ═══'); + + const typedData = await tronClient.createExecuteTypedData({ + contractAddress, + operation: payoutOperation, + }); + + const { domain, types, message } = transactions.prepareTronTypedDataForSigning(typedData); + const signature = await tronWeb.trx._signTypedData(domain, types, message); + console.log('Signature:', `${signature.slice(0, 20)}...`); + + const signatureResponse = await client.submitOperationSignature({ + operationId: payoutOperation.id, + signature, + signerAddress: signerAddress as string, + }); + + console.log('Signature submitted:'); + console.table({ + operationId: signatureResponse.operationId, + signaturesCollected: signatureResponse.signaturesCollected, + signaturesRequired: signatureResponse.signaturesRequired, + }); + + // ─── Step 7: Execute ────────────────────────────────────────────────────────── + console.log('\n═══ Step 7: Execute ═══'); + + const operationsToExecute = await poll( + 'executable operation', + async () => { + const queue = await client.getDeploymentQueue({ statuses: ['READY'], pageSize: 100 }); + + const payoutReady = queue.items.some((item) => item.id === payoutOperation.id); + if (!payoutReady) return null; + + const batch: QueueOperation[] = []; + let currentNonce = Number(queue.nextExecutableNonce); + for (const item of queue.items) { + if (item.nonce !== currentNonce.toString()) break; + if (item.signaturesCollected < item.signaturesRequired) break; + batch.push(item); + currentNonce++; + } + + const includesOurOp = batch.some((item) => item.id === payoutOperation.id); + return includesOurOp ? batch : null; + }, + pollInterval, + pollTimeout, + ); + + console.log(`Executing ${operationsToExecute.length} operation(s) in batch:`); + console.table(operationsToExecute.map((op) => ({ id: op.id, nonce: op.nonce, type: op.operationType }))); + + const executeTx = await tronClient.buildExecuteTransaction({ + contractAddress, + callerAddress, + operations: operationsToExecute, + }); + + const signedExecuteTx = await tronWeb.trx.sign(executeTx.raw as Parameters[0]); + const executeResult = await tronWeb.trx.sendRawTransaction( + signedExecuteTx as Parameters[0], + ); + + const executeTxId: string = executeResult.txid; + console.log('Execute tx broadcasted:', executeTxId); + + await waitForTronReceipt(tronWeb, executeTxId); + console.log('Execute tx confirmed on-chain.'); + + console.log('Waiting for payout transaction confirmation via API...'); + const confirmedPayout = await waitForTxConfirmation( + client, + executeTxId, + TransactionOperationType.Payout, + pollInterval, + pollTimeout, + ); + console.log(`Payout confirmed: ${confirmedPayout.confirmations} confirmations`); + + // ─── Step 8: Summary ────────────────────────────────────────────────────────── + console.log('\n═══ Step 8: Final balances ═══'); + + const finalBalances = await client.getAssetBalances({ + chainId, + baseCurrency: BASE_CURRENCY, + sortBy: AssetSortField.Balance, + sortOrder: AssetSortOrder.Desc, + pageSize: 20, + }); + + const nonZeroFinal = finalBalances.items.filter((b) => Number(b.balance) > 0); + if (nonZeroFinal.length > 0) { + console.table(nonZeroFinal.map((b) => ({ symbol: b.currency.symbol, balance: b.balance }))); + } else { + console.log('All balances are zero after the flow.'); + } + + const finalSummary = await client.getAccountBalanceSummary({ chainId: chainIdNumber, baseCurrency: BASE_CURRENCY }); + console.log('Final balance summary (USD):'); + console.table({ + total: finalSummary.totalBalance, + uncollected: finalSummary.uncollectedBalance, + uncollectedInvoices: finalSummary.uncollectedInvoices, + }); + + console.log('\n✓ Full Tron flow completed successfully.'); +}); + +async function waitForTronReceipt(tronWeb: TronWeb, txId: string): Promise { + const deadline = Date.now() + TX_RECEIPT_TIMEOUT_MS; + + while (Date.now() < deadline) { + try { + const info = await tronWeb.trx.getTransactionInfo(txId); + if (info && 'blockNumber' in info && info.blockNumber) { + return; + } + } catch { + // Transaction not yet indexed, retry + } + + await new Promise((resolve) => setTimeout(resolve, TX_RECEIPT_POLL_MS)); + } + + throw new Error(`Transaction receipt for ${txId} not found after ${TX_RECEIPT_TIMEOUT_MS / 1000}s`); +} + +async function waitForTxConfirmation( + apiClient: DefiClient, + txHash: string, + operationType: TransactionOperationType, + pollIntervalMs: number, + pollTimeoutMs: number, +): Promise { + const tx = await poll( + `${operationType} transaction`, + async () => { + const result = await apiClient.getTransactions({ operationTypes: [operationType], pageSize: 50 }); + return result.items.find((item) => item.txHash === txHash) ?? null; + }, + pollIntervalMs, + pollTimeoutMs, + ); + + if (tx.status === TransactionStatus.Confirmed) return tx; + + return poll( + `${operationType} confirmation`, + async () => { + const result = await apiClient.getTransactions({ operationTypes: [operationType], pageSize: 50 }); + const found = result.items.find((item) => item.id === tx.id); + if (!found) return null; + console.log(` confirmations: ${found.confirmations}, status: ${found.status}`); + return found.status === TransactionStatus.Confirmed ? found : null; + }, + pollIntervalMs, + pollTimeoutMs, + ); +} + +async function poll(label: string, fn: () => Promise, intervalMs: number, timeoutMs: number): Promise { + const deadline = Date.now() + timeoutMs; + + while (Date.now() < deadline) { + const result = await fn(); + if (result !== null) { + return result; + } + + const remaining = Math.round((deadline - Date.now()) / 1000); + console.log(`[${label}] not ready — retrying in ${intervalMs / 1000}s (${remaining}s remaining)...`); + await new Promise((resolve) => setTimeout(resolve, intervalMs)); + } + + throw new Error(`[${label}] timed out after ${timeoutMs / 1000}s`); +} diff --git a/examples/tron-get-account-info.ts b/examples/tron-get-account-info.ts new file mode 100644 index 0000000..42e8818 --- /dev/null +++ b/examples/tron-get-account-info.ts @@ -0,0 +1,69 @@ +/** + * Tron: Get account info use case: + * - Authenticate with API key only (no wallet required). + * - Fetch account details and filter Tron deployments. + * - For every Tron deployment, print balance summary and list non-zero asset balances. + */ +import 'dotenv/config'; +import { AssetSortField, AssetSortOrder, DefiClient, FiatCurrency, TRON_CHAIN_IDS } from '../src'; +import { requireEnvVars, runMain } from './utils'; + +const requiredEnv = ['API_BASE_URL', 'API_KEY'] as const; + +runMain(async () => { + const env = requireEnvVars(requiredEnv); + const baseCurrency = FiatCurrency.Usd; + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + + const accountDetails = await client.getAccount(); + console.log('Selected account:', accountDetails.account.name, accountDetails.account.id); + + const deployments = await client.getDeployments(accountDetails); + const tronDeployments = deployments.filter((d) => TRON_CHAIN_IDS.has(Number(d.chainId))); + + if (tronDeployments.length === 0) { + throw new Error('No Tron deployments found for this account.'); + } + + console.log(`Found ${tronDeployments.length} Tron deployment(s). Fetching balances...`); + + for (const deployment of tronDeployments) { + const chainIdNumber = Number.parseInt(deployment.chainId, 10); + console.log(`\nTron Chain ${deployment.chainId}`); + + const summary = await client.getAccountBalanceSummary({ + chainId: chainIdNumber, + baseCurrency, + }); + + console.table({ + total: summary.totalBalance, + uncollectedBalance: summary.uncollectedBalance, + uncollectedInvoices: summary.uncollectedInvoices, + }); + + const balances = await client.getAssetBalances({ + chainId: deployment.chainId, + baseCurrency, + sortBy: AssetSortField.Balance, + sortOrder: AssetSortOrder.Desc, + pageSize: 100, + }); + + const nonZeroBalances = balances.items.filter((item) => Number(item.balance) > 0); + + if (nonZeroBalances.length === 0) { + console.log('No non-zero balances on this Tron deployment.'); + continue; + } + + console.table( + nonZeroBalances.map((item) => ({ + symbol: item.currency.symbol, + balance: item.balance, + converted: `${item.convertedBalance} ${baseCurrency.toUpperCase()}`, + })), + ); + } +}); diff --git a/examples/tron-queue-execute-batch.ts b/examples/tron-queue-execute-batch.ts new file mode 100644 index 0000000..934b29b --- /dev/null +++ b/examples/tron-queue-execute-batch.ts @@ -0,0 +1,80 @@ +/** + * Tron: Queue batch execute use case: + * - Authenticate via API key. + * - Find consecutive ready-to-execute operations on the Tron network. + * - Build one execute transaction covering all operations, sign and broadcast via TronWeb. + */ +import 'dotenv/config'; +import { TronWeb } from 'tronweb'; +import { DefiClient, type QueueOperation, type TronAddress, TronMultisigBlockchainClient } from '../src'; +import { DEFAULT_FEE_LIMIT, parseChainId, requireEnvVars, runMain } from './utils'; + +const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'RPC_URL', 'WALLET_PRIVATE_KEY'] as const; + +runMain(async () => { + const env = requireEnvVars(requiredEnv); + const chainId = parseChainId(env.CHAIN_ID); + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + const accountDetails = await client.getAccount(); + await client.selectChain(chainId); + + const queue = await client.getDeploymentQueue({ statuses: ['READY'], pageSize: 50 }); + const operationsToExecute: QueueOperation[] = []; + + let currentNonce = Number(queue.nextExecutableNonce); + for (const item of queue.items) { + if (item.nonce !== currentNonce.toString()) { + break; + } + if (item.signaturesCollected < item.signaturesRequired) { + break; + } + operationsToExecute.push(item); + currentNonce++; + } + + if (operationsToExecute.length === 0) { + throw new Error('No executable operations found in the Tron queue.'); + } + + console.log('Found Tron operations to execute:'); + console.table( + operationsToExecute.map((op) => ({ + id: op.id, + nonce: op.nonce, + type: op.operationType, + signatures: `${op.signaturesCollected}/${op.signaturesRequired}`, + })), + ); + + const tronWeb = new TronWeb({ + fullHost: env.RPC_URL, + privateKey: env.WALLET_PRIVATE_KEY, + }); + + const contractAbi = await client.getContractAbi(); + + const tronClient = new TronMultisigBlockchainClient({ + chainId, + tronWeb, + contractAbi, + defaultFeeLimit: DEFAULT_FEE_LIMIT, + }); + + const callerAddress = TronWeb.address.fromPrivateKey(env.WALLET_PRIVATE_KEY); + if (!callerAddress) { + throw new Error('Failed to derive Tron address from private key.'); + } + + const transaction = await tronClient.buildExecuteTransaction({ + contractAddress: accountDetails.account.contract as TronAddress, + callerAddress: callerAddress as TronAddress, + operations: operationsToExecute, + }); + + const signedTx = await tronWeb.trx.sign(transaction.raw as Parameters[0]); + const result = await tronWeb.trx.sendRawTransaction(signedTx as Parameters[0]); + + console.log('Tron batch execution broadcasted:', result.txid); +}); diff --git a/examples/tron-queue-execute.ts b/examples/tron-queue-execute.ts new file mode 100644 index 0000000..f61f03c --- /dev/null +++ b/examples/tron-queue-execute.ts @@ -0,0 +1,58 @@ +/** + * Tron: Queue execute use case: + * - Authenticate via API key. + * - Find the first Tron operation that is ready to execute. + * - Build execute transaction, sign and broadcast via TronWeb. + */ +import 'dotenv/config'; +import { TronWeb } from 'tronweb'; +import { DefiClient, type TronAddress, TronMultisigBlockchainClient } from '../src'; +import { DEFAULT_FEE_LIMIT, parseChainId, requireEnvVars, runMain } from './utils'; + +const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'RPC_URL', 'WALLET_PRIVATE_KEY'] as const; + +runMain(async () => { + const env = requireEnvVars(requiredEnv); + const chainId = parseChainId(env.CHAIN_ID); + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + const accountDetails = await client.getAccount(); + await client.selectChain(chainId); + + const queue = await client.getDeploymentQueue({ pageSize: 50 }); + const executable = queue.items.find((item) => item.canExecute && !item.isBlocked); + + if (!executable) { + throw new Error('No executable operations found in the Tron queue.'); + } + + const tronWeb = new TronWeb({ + fullHost: env.RPC_URL, + privateKey: env.WALLET_PRIVATE_KEY, + }); + + const contractAbi = await client.getContractAbi(); + + const tronClient = new TronMultisigBlockchainClient({ + chainId, + tronWeb, + contractAbi, + defaultFeeLimit: DEFAULT_FEE_LIMIT, + }); + + const callerAddress = TronWeb.address.fromPrivateKey(env.WALLET_PRIVATE_KEY); + if (!callerAddress) { + throw new Error('Failed to derive Tron address from private key.'); + } + + const transaction = await tronClient.buildExecuteTransaction({ + contractAddress: accountDetails.account.contract as TronAddress, + callerAddress: callerAddress as TronAddress, + operations: [executable], + }); + + const signedTx = await tronWeb.trx.sign(transaction.raw as Parameters[0]); + const result = await tronWeb.trx.sendRawTransaction(signedTx as Parameters[0]); + + console.log('Tron execution broadcasted:', result.txid); +}); diff --git a/examples/tron-queue-sign.ts b/examples/tron-queue-sign.ts new file mode 100644 index 0000000..7b2b857 --- /dev/null +++ b/examples/tron-queue-sign.ts @@ -0,0 +1,83 @@ +/** + * Tron: Queue signing use case: + * - Authenticate via API key and set up TronWeb with private key. + * - Fetch deployment queue and find the first signable operation. + * - Build TIP-712 typed data and submit the signature. + */ +import 'dotenv/config'; +import { TronWeb } from 'tronweb'; +import { DefiClient, type TronAddress, TronMultisigBlockchainClient, transactions } from '../src'; +import { DEFAULT_FEE_LIMIT, parseChainId, requireEnvVars, runMain } from './utils'; + +const requiredEnv = ['API_BASE_URL', 'API_KEY', 'CHAIN_ID', 'RPC_URL', 'WALLET_PRIVATE_KEY'] as const; + +runMain(async () => { + const env = requireEnvVars(requiredEnv); + const chainId = parseChainId(env.CHAIN_ID); + + const tronWeb = new TronWeb({ + fullHost: env.RPC_URL, + privateKey: env.WALLET_PRIVATE_KEY, + }); + + const signerAddress = TronWeb.address.fromPrivateKey(env.WALLET_PRIVATE_KEY); + if (!signerAddress) { + throw new Error('Failed to derive Tron address from private key.'); + } + console.log('Using Tron signer:', signerAddress); + + const client = new DefiClient({ baseUrl: env.API_BASE_URL, apiKey: env.API_KEY }); + const accountDetails = await client.getAccount(); + await client.selectChain(chainId); + + const queue = await client.getDeploymentQueue({ pageSize: 50 }); + const operation = queue.items.find((item) => { + const signed = item.signatures.some((sig) => sig.user.toLowerCase() === signerAddress.toLowerCase()); + return !signed; + }); + + if (!operation) { + throw new Error('No signable operations found in the Tron queue.'); + } + + console.log('Signing Tron operation:'); + console.table({ + id: operation.id, + nonce: operation.nonce, + type: operation.operationType, + signaturesCollected: operation.signaturesCollected, + signaturesRequired: operation.signaturesRequired, + }); + + const contractAbi = await client.getContractAbi(); + + const tronClient = new TronMultisigBlockchainClient({ + chainId, + tronWeb, + contractAbi, + defaultFeeLimit: DEFAULT_FEE_LIMIT, + }); + + const typedData = await tronClient.createExecuteTypedData({ + contractAddress: accountDetails.account.contract as TronAddress, + operation, + }); + + // Sign the TIP-712 typed data using TronWeb._signTypedData + // This performs proper EIP-712/TIP-712 hash computation and signing + const { domain, types, message } = transactions.prepareTronTypedDataForSigning(typedData); + const signature = await tronWeb.trx._signTypedData(domain, types, message); + + const signatureResponse = await client.submitOperationSignature({ + operationId: operation.id, + signature, + signerAddress: signerAddress as string, + }); + + console.log('Submitted Tron signature:'); + console.table({ + operationId: signatureResponse.operationId, + signaturesCollected: signatureResponse.signaturesCollected, + signaturesRequired: signatureResponse.signaturesRequired, + }); +}); diff --git a/examples/utils.ts b/examples/utils.ts index 74c2fe1..d6eed11 100644 --- a/examples/utils.ts +++ b/examples/utils.ts @@ -1,5 +1,8 @@ import { ResponseError } from '../generated-contracts'; +/** Default Tron fee limit in SUN (150 TRX). Used by example scripts when constructing TronMultisigBlockchainClient. */ +export const DEFAULT_FEE_LIMIT = 150_000_000; + export type EnvRecord = { [K in TKeys[number]]: string; }; diff --git a/generated-contracts/.openapi-generator/FILES b/generated-contracts/.openapi-generator/FILES index 7f3263a..b371a0d 100644 --- a/generated-contracts/.openapi-generator/FILES +++ b/generated-contracts/.openapi-generator/FILES @@ -11,44 +11,23 @@ apis/queue-operations-api.ts apis/smart-contract-versions-api.ts apis/transactions-api.ts index.ts -models/account-currency-visibility-response-dto.ts models/account-deployment-dto.ts models/account-details-dto.ts models/account-response-dto.ts -models/address-book-entry-response-dto.ts -models/address-book-list-response-dto-items-inner.ts -models/address-book-list-response-dto.ts -models/api-key-list-response-dto-items-inner.ts -models/api-key-list-response-dto.ts -models/api-key-meta-dto.ts models/asset-balance-dto.ts +models/asset-balance-short-response-dto.ts models/asset-balances-response-dto.ts -models/auth-response-dto.ts -models/balance-history-response-dto-items-inner.ts -models/balance-history-response-dto.ts models/balance-summary-response-dto.ts models/call-dto.ts -models/callback-secret-response-dto.ts models/callback.ts models/claim-item-dto.ts models/claims-response-dto.ts -models/create-account-dto.ts -models/create-address-book-entry-dto.ts -models/create-api-key-dto.ts -models/create-api-key-response-dto.ts models/create-invoice-dto.ts -models/create-multisig-config-change-operation-dto-calls-inner.ts models/create-multisig-config-change-operation-dto.ts -models/create-payment-body-dto.ts models/create-payout-dto.ts models/create-reject-operation-dto.ts -models/credit-price-item-dto.ts -models/credits-overview-response-dto-unit-prices-inner-discounts-inner.ts -models/credits-overview-response-dto-unit-prices-inner.ts -models/credits-overview-response-dto.ts models/currencies-controller-find-all-v1-is-native-parameter.ts models/currency-response-dto.ts -models/delete-all-operations-response-dto.ts models/deployment-params-response-dto.ts models/deployment-queue-response-dto.ts models/get-callbacks-response-dto.ts @@ -59,32 +38,17 @@ models/invoices-response-dto.ts models/network-response-dto.ts models/networks-response-dto.ts models/nonce-info-response-dto.ts -models/nonce-request-dto.ts -models/nonce-response-dto.ts -models/operation-catalog-item-dto.ts models/operation-signature-dto.ts -models/operation-usages-response-dto-items-inner-api-operation.ts -models/operation-usages-response-dto-items-inner.ts -models/operation-usages-response-dto.ts models/payout-detail-response-dto.ts models/payout-list-response-dto.ts models/payout-response-dto.ts -models/post-rates-body-dto.ts -models/profile-response-dto.ts -models/public-invoice-response-dto.ts -models/public-transaction-list-response-dto.ts -models/public-transaction-response-dto.ts +models/queue-operation-response-dto-dapp-metadata.ts models/queue-operation-response-dto.ts -models/rate-pair-dto.ts -models/rate-result-dto.ts -models/rates-response-dto.ts -models/refresh-token-request-dto.ts +models/resend-callbacks-body-dto.ts +models/resend-callbacks-response-dto.ts models/signature-response-dto.ts models/smart-contract-version-response-dto.ts models/submit-signature-dto.ts -models/top-ups-response-dto-items-inner-currency.ts -models/top-ups-response-dto-items-inner.ts -models/top-ups-response-dto.ts models/transaction-details-dto.ts models/transaction-invoice-response-dto.ts models/transaction-list-response-dto.ts @@ -93,11 +57,7 @@ models/transactions-controller-get-transactions-v1-currency-is-scam-parameter.ts models/transactions-controller-get-transactions-v1-currency-is-verified-parameter.ts models/universal-address.ts models/update-account-dto.ts -models/update-address-book-entry-dto.ts models/update-invoice-dto.ts models/update-operation-nonce-dto.ts models/update-payout-dto.ts -models/update-profile-request-dto.ts -models/user-response-dto.ts -models/verify-request-dto.ts runtime.ts diff --git a/generated-contracts/apis/accounts-api.ts b/generated-contracts/apis/accounts-api.ts index 55c22b2..5c72e80 100644 --- a/generated-contracts/apis/accounts-api.ts +++ b/generated-contracts/apis/accounts-api.ts @@ -17,9 +17,9 @@ import * as runtime from '../runtime'; import type { AccountDetailsDto, AccountResponseDto, + AssetBalanceShortResponseDto, AssetBalancesResponseDto, BalanceSummaryResponseDto, - CallbackSecretResponseDto, CurrenciesControllerFindAllV1IsNativeParameter, DeploymentParamsResponseDto, NonceInfoResponseDto, @@ -31,12 +31,12 @@ import { AccountDetailsDtoToJSON, AccountResponseDtoFromJSON, AccountResponseDtoToJSON, + AssetBalanceShortResponseDtoFromJSON, + AssetBalanceShortResponseDtoToJSON, AssetBalancesResponseDtoFromJSON, AssetBalancesResponseDtoToJSON, BalanceSummaryResponseDtoFromJSON, BalanceSummaryResponseDtoToJSON, - CallbackSecretResponseDtoFromJSON, - CallbackSecretResponseDtoToJSON, CurrenciesControllerFindAllV1IsNativeParameterFromJSON, CurrenciesControllerFindAllV1IsNativeParameterToJSON, DeploymentParamsResponseDtoFromJSON, @@ -61,10 +61,6 @@ export interface AccountsControllerFindUserAccountsV1Request { isHidden?: TransactionsControllerGetTransactionsV1CurrencyIsScamParameter; } -export interface AccountsControllerGenerateCallbackSecretV1Request { - accountId: string; -} - export interface AccountsControllerGetAssetBalancesV1Request { accountId: string; baseCurrency: AccountsControllerGetAssetBalancesV1BaseCurrencyEnum; @@ -89,6 +85,15 @@ export interface AccountsControllerGetDeploymentInfoV1Request { accountId: string; } +export interface AccountsControllerGetShortAssetBalancesV1Request { + accountId: string; + chainId: string; + currencyIds?: Array; + isScam?: CurrenciesControllerFindAllV1IsNativeParameter; + isVerified?: CurrenciesControllerFindAllV1IsNativeParameter; + isHidden?: CurrenciesControllerFindAllV1IsNativeParameter; +} + export interface AccountsControllerUpdateAccountV1Request { accountId: string; updateAccountDto: UpdateAccountDto; @@ -224,49 +229,6 @@ export class AccountsApi extends runtime.BaseAPI { return await response.value(); } - /** - * Generates a new callback secret for the account. The secret is returned only once and instantly invalidates the old secret. - * Generate callback secret - */ - async accountsControllerGenerateCallbackSecretV1Raw(requestParameters: AccountsControllerGenerateCallbackSecretV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters['accountId'] == null) { - throw new runtime.RequiredError( - 'accountId', - 'Required parameter "accountId" was null or undefined when calling accountsControllerGenerateCallbackSecretV1().' - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = await this.configuration.apiKey("x-api-key"); // ApiKeyAuth authentication - } - - - let urlPath = `/api/v1/accounts/{accountId}/callback-secret`; - urlPath = urlPath.replace(`{${"accountId"}}`, encodeURIComponent(String(requestParameters['accountId']))); - - const response = await this.request({ - path: urlPath, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); - - return new runtime.JSONApiResponse(response, (jsonValue) => CallbackSecretResponseDtoFromJSON(jsonValue)); - } - - /** - * Generates a new callback secret for the account. The secret is returned only once and instantly invalidates the old secret. - * Generate callback secret - */ - async accountsControllerGenerateCallbackSecretV1(requestParameters: AccountsControllerGenerateCallbackSecretV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.accountsControllerGenerateCallbackSecretV1Raw(requestParameters, initOverrides); - return await response.value(); - } - /** * Returns balances for each asset with conversion to base currency for a specific network with pagination * Get asset balances @@ -472,6 +434,76 @@ export class AccountsApi extends runtime.BaseAPI { return await response.value(); } + /** + * Returns asset balances without conversion and pagination. Response is a flat array of items. + * Get asset balances (short) + */ + async accountsControllerGetShortAssetBalancesV1Raw(requestParameters: AccountsControllerGetShortAssetBalancesV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters['accountId'] == null) { + throw new runtime.RequiredError( + 'accountId', + 'Required parameter "accountId" was null or undefined when calling accountsControllerGetShortAssetBalancesV1().' + ); + } + + if (requestParameters['chainId'] == null) { + throw new runtime.RequiredError( + 'chainId', + 'Required parameter "chainId" was null or undefined when calling accountsControllerGetShortAssetBalancesV1().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['currencyIds'] != null) { + queryParameters['currencyIds'] = requestParameters['currencyIds']; + } + + if (requestParameters['isScam'] != null) { + queryParameters['isScam'] = requestParameters['isScam']; + } + + if (requestParameters['isVerified'] != null) { + queryParameters['isVerified'] = requestParameters['isVerified']; + } + + if (requestParameters['isHidden'] != null) { + queryParameters['isHidden'] = requestParameters['isHidden']; + } + + if (requestParameters['chainId'] != null) { + queryParameters['chainId'] = requestParameters['chainId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = await this.configuration.apiKey("x-api-key"); // ApiKeyAuth authentication + } + + + let urlPath = `/api/v1/accounts/{accountId}/balances`; + urlPath = urlPath.replace(`{${"accountId"}}`, encodeURIComponent(String(requestParameters['accountId']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetBalanceShortResponseDtoFromJSON)); + } + + /** + * Returns asset balances without conversion and pagination. Response is a flat array of items. + * Get asset balances (short) + */ + async accountsControllerGetShortAssetBalancesV1(requestParameters: AccountsControllerGetShortAssetBalancesV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.accountsControllerGetShortAssetBalancesV1Raw(requestParameters, initOverrides); + return await response.value(); + } + /** * Update entity * Update diff --git a/generated-contracts/apis/callbacks-api.ts b/generated-contracts/apis/callbacks-api.ts index e072030..3a68a26 100644 --- a/generated-contracts/apis/callbacks-api.ts +++ b/generated-contracts/apis/callbacks-api.ts @@ -16,10 +16,16 @@ import * as runtime from '../runtime'; import type { GetCallbacksResponseDto, + ResendCallbacksBodyDto, + ResendCallbacksResponseDto, } from '../models/index'; import { GetCallbacksResponseDtoFromJSON, GetCallbacksResponseDtoToJSON, + ResendCallbacksBodyDtoFromJSON, + ResendCallbacksBodyDtoToJSON, + ResendCallbacksResponseDtoFromJSON, + ResendCallbacksResponseDtoToJSON, } from '../models/index'; export interface CallbacksControllerGetCallbacksV1Request { @@ -28,6 +34,10 @@ export interface CallbacksControllerGetCallbacksV1Request { pageSize?: number; } +export interface CallbacksControllerResendCallbacksV1Request { + resendCallbacksBodyDto: ResendCallbacksBodyDto; +} + /** * */ @@ -87,4 +97,49 @@ export class CallbacksApi extends runtime.BaseAPI { return await response.value(); } + /** + * Re-queue failed callbacks for delivery by resetting their status. Only FAILED callbacks owned by the current user are eligible. + * Resend failed callbacks + */ + async callbacksControllerResendCallbacksV1Raw(requestParameters: CallbacksControllerResendCallbacksV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['resendCallbacksBodyDto'] == null) { + throw new runtime.RequiredError( + 'resendCallbacksBodyDto', + 'Required parameter "resendCallbacksBodyDto" was null or undefined when calling callbacksControllerResendCallbacksV1().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = await this.configuration.apiKey("x-api-key"); // ApiKeyAuth authentication + } + + + let urlPath = `/api/v1/callbacks/resend`; + + const response = await this.request({ + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ResendCallbacksBodyDtoToJSON(requestParameters['resendCallbacksBodyDto']), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ResendCallbacksResponseDtoFromJSON(jsonValue)); + } + + /** + * Re-queue failed callbacks for delivery by resetting their status. Only FAILED callbacks owned by the current user are eligible. + * Resend failed callbacks + */ + async callbacksControllerResendCallbacksV1(requestParameters: CallbacksControllerResendCallbacksV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.callbacksControllerResendCallbacksV1Raw(requestParameters, initOverrides); + return await response.value(); + } + } diff --git a/generated-contracts/apis/currencies-api.ts b/generated-contracts/apis/currencies-api.ts index 89f9a90..1ca50c0 100644 --- a/generated-contracts/apis/currencies-api.ts +++ b/generated-contracts/apis/currencies-api.ts @@ -166,7 +166,8 @@ export class CurrenciesApi extends runtime.BaseAPI { */ export const CurrenciesControllerFindAllV1SortByEnum = { CreatedAt: 'createdAt', - UpdatedAt: 'updatedAt' + UpdatedAt: 'updatedAt', + CmcId: 'cmcId' } as const; export type CurrenciesControllerFindAllV1SortByEnum = typeof CurrenciesControllerFindAllV1SortByEnum[keyof typeof CurrenciesControllerFindAllV1SortByEnum]; /** diff --git a/generated-contracts/apis/invoices-api.ts b/generated-contracts/apis/invoices-api.ts index 653f7c8..72e88a7 100644 --- a/generated-contracts/apis/invoices-api.ts +++ b/generated-contracts/apis/invoices-api.ts @@ -16,29 +16,20 @@ import * as runtime from '../runtime'; import type { CreateInvoiceDto, - CurrenciesControllerFindAllV1IsNativeParameter, InvoiceDetailsDto, InvoiceResponseDto, InvoicesResponseDto, - PublicInvoiceResponseDto, - PublicTransactionListResponseDto, UpdateInvoiceDto, } from '../models/index'; import { CreateInvoiceDtoFromJSON, CreateInvoiceDtoToJSON, - CurrenciesControllerFindAllV1IsNativeParameterFromJSON, - CurrenciesControllerFindAllV1IsNativeParameterToJSON, InvoiceDetailsDtoFromJSON, InvoiceDetailsDtoToJSON, InvoiceResponseDtoFromJSON, InvoiceResponseDtoToJSON, InvoicesResponseDtoFromJSON, InvoicesResponseDtoToJSON, - PublicInvoiceResponseDtoFromJSON, - PublicInvoiceResponseDtoToJSON, - PublicTransactionListResponseDtoFromJSON, - PublicTransactionListResponseDtoToJSON, UpdateInvoiceDtoFromJSON, UpdateInvoiceDtoToJSON, } from '../models/index'; @@ -75,27 +66,6 @@ export interface InvoicesControllerUpdateInvoiceV1Request { updateInvoiceDto: UpdateInvoiceDto; } -export interface PublicInvoicesControllerGetPublicInvoiceTransactionsV1Request { - publicId: string; - txHash?: string; - currencyIds?: Array; - statuses?: Array; - operationTypes?: Array; - createdFrom?: string; - createdTo?: string; - page?: number; - pageSize?: number; - id?: string; - updatedFrom?: string; - updatedTo?: string; - operationId?: string; - isClaimed?: CurrenciesControllerFindAllV1IsNativeParameter; -} - -export interface PublicInvoicesControllerGetPublicInvoiceV1Request { - publicId: string; -} - /** * */ @@ -357,144 +327,6 @@ export class InvoicesApi extends runtime.BaseAPI { return await response.value(); } - /** - * Get list of transactions for a public invoice without authentication - * Get public invoice transactions - */ - async publicInvoicesControllerGetPublicInvoiceTransactionsV1Raw(requestParameters: PublicInvoicesControllerGetPublicInvoiceTransactionsV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters['publicId'] == null) { - throw new runtime.RequiredError( - 'publicId', - 'Required parameter "publicId" was null or undefined when calling publicInvoicesControllerGetPublicInvoiceTransactionsV1().' - ); - } - - const queryParameters: any = {}; - - if (requestParameters['txHash'] != null) { - queryParameters['txHash'] = requestParameters['txHash']; - } - - if (requestParameters['currencyIds'] != null) { - queryParameters['currencyIds'] = requestParameters['currencyIds']; - } - - if (requestParameters['statuses'] != null) { - queryParameters['statuses'] = requestParameters['statuses']; - } - - if (requestParameters['operationTypes'] != null) { - queryParameters['operationTypes'] = requestParameters['operationTypes']; - } - - if (requestParameters['createdFrom'] != null) { - queryParameters['createdFrom'] = requestParameters['createdFrom']; - } - - if (requestParameters['createdTo'] != null) { - queryParameters['createdTo'] = requestParameters['createdTo']; - } - - if (requestParameters['page'] != null) { - queryParameters['page'] = requestParameters['page']; - } - - if (requestParameters['pageSize'] != null) { - queryParameters['pageSize'] = requestParameters['pageSize']; - } - - if (requestParameters['id'] != null) { - queryParameters['id'] = requestParameters['id']; - } - - if (requestParameters['updatedFrom'] != null) { - queryParameters['updatedFrom'] = requestParameters['updatedFrom']; - } - - if (requestParameters['updatedTo'] != null) { - queryParameters['updatedTo'] = requestParameters['updatedTo']; - } - - if (requestParameters['operationId'] != null) { - queryParameters['operationId'] = requestParameters['operationId']; - } - - if (requestParameters['isClaimed'] != null) { - queryParameters['isClaimed'] = requestParameters['isClaimed']; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = await this.configuration.apiKey("x-api-key"); // ApiKeyAuth authentication - } - - - let urlPath = `/api/v1/public/invoices/{publicId}/transactions`; - urlPath = urlPath.replace(`{${"publicId"}}`, encodeURIComponent(String(requestParameters['publicId']))); - - const response = await this.request({ - path: urlPath, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); - - return new runtime.JSONApiResponse(response, (jsonValue) => PublicTransactionListResponseDtoFromJSON(jsonValue)); - } - - /** - * Get list of transactions for a public invoice without authentication - * Get public invoice transactions - */ - async publicInvoicesControllerGetPublicInvoiceTransactionsV1(requestParameters: PublicInvoicesControllerGetPublicInvoiceTransactionsV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.publicInvoicesControllerGetPublicInvoiceTransactionsV1Raw(requestParameters, initOverrides); - return await response.value(); - } - - /** - * Get public invoice information without authentication - * Get public invoice details - */ - async publicInvoicesControllerGetPublicInvoiceV1Raw(requestParameters: PublicInvoicesControllerGetPublicInvoiceV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters['publicId'] == null) { - throw new runtime.RequiredError( - 'publicId', - 'Required parameter "publicId" was null or undefined when calling publicInvoicesControllerGetPublicInvoiceV1().' - ); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = await this.configuration.apiKey("x-api-key"); // ApiKeyAuth authentication - } - - - let urlPath = `/api/v1/public/invoices/{publicId}`; - urlPath = urlPath.replace(`{${"publicId"}}`, encodeURIComponent(String(requestParameters['publicId']))); - - const response = await this.request({ - path: urlPath, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); - - return new runtime.JSONApiResponse(response, (jsonValue) => PublicInvoiceResponseDtoFromJSON(jsonValue)); - } - - /** - * Get public invoice information without authentication - * Get public invoice details - */ - async publicInvoicesControllerGetPublicInvoiceV1(requestParameters: PublicInvoicesControllerGetPublicInvoiceV1Request, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.publicInvoicesControllerGetPublicInvoiceV1Raw(requestParameters, initOverrides); - return await response.value(); - } - } /** @@ -523,25 +355,3 @@ export const InvoicesControllerFindInvoicesByDeploymentV1StatusesEnum = { Unresolved: 'UNRESOLVED' } as const; export type InvoicesControllerFindInvoicesByDeploymentV1StatusesEnum = typeof InvoicesControllerFindInvoicesByDeploymentV1StatusesEnum[keyof typeof InvoicesControllerFindInvoicesByDeploymentV1StatusesEnum]; -/** - * @export - */ -export const PublicInvoicesControllerGetPublicInvoiceTransactionsV1StatusesEnum = { - Pending: 'PENDING', - Executed: 'EXECUTED', - Confirmed: 'CONFIRMED', - Failed: 'FAILED' -} as const; -export type PublicInvoicesControllerGetPublicInvoiceTransactionsV1StatusesEnum = typeof PublicInvoicesControllerGetPublicInvoiceTransactionsV1StatusesEnum[keyof typeof PublicInvoicesControllerGetPublicInvoiceTransactionsV1StatusesEnum]; -/** - * @export - */ -export const PublicInvoicesControllerGetPublicInvoiceTransactionsV1OperationTypesEnum = { - Invoice: 'invoice', - DirectDeposit: 'direct_deposit', - SetConfig: 'set_config', - Claim: 'claim', - Payout: 'payout', - Reject: 'reject' -} as const; -export type PublicInvoicesControllerGetPublicInvoiceTransactionsV1OperationTypesEnum = typeof PublicInvoicesControllerGetPublicInvoiceTransactionsV1OperationTypesEnum[keyof typeof PublicInvoicesControllerGetPublicInvoiceTransactionsV1OperationTypesEnum]; diff --git a/generated-contracts/apis/queue-operations-api.ts b/generated-contracts/apis/queue-operations-api.ts index 06fd289..fba713c 100644 --- a/generated-contracts/apis/queue-operations-api.ts +++ b/generated-contracts/apis/queue-operations-api.ts @@ -57,14 +57,14 @@ export interface QueueOperationsControllerDeleteOperationV1Request { export interface QueueOperationsControllerGetDeploymentQueueV1Request { deploymentId: string; + page?: number; + pageSize?: number; statuses?: Array; operationTypes?: Array; - createdAtFrom?: Date; - createdAtTo?: Date; createdBy?: string; sortOrder?: QueueOperationsControllerGetDeploymentQueueV1SortOrderEnum; - page?: number; - pageSize?: number; + createdAtFrom?: string; + createdAtTo?: string; } export interface QueueOperationsControllerGetOperationByIdV1Request { @@ -259,20 +259,20 @@ export class QueueOperationsApi extends runtime.BaseAPI { const queryParameters: any = {}; - if (requestParameters['statuses'] != null) { - queryParameters['statuses'] = requestParameters['statuses']; + if (requestParameters['page'] != null) { + queryParameters['page'] = requestParameters['page']; } - if (requestParameters['operationTypes'] != null) { - queryParameters['operationTypes'] = requestParameters['operationTypes']; + if (requestParameters['pageSize'] != null) { + queryParameters['pageSize'] = requestParameters['pageSize']; } - if (requestParameters['createdAtFrom'] != null) { - queryParameters['createdAtFrom'] = (requestParameters['createdAtFrom'] as any).toISOString(); + if (requestParameters['statuses'] != null) { + queryParameters['statuses'] = requestParameters['statuses']; } - if (requestParameters['createdAtTo'] != null) { - queryParameters['createdAtTo'] = (requestParameters['createdAtTo'] as any).toISOString(); + if (requestParameters['operationTypes'] != null) { + queryParameters['operationTypes'] = requestParameters['operationTypes']; } if (requestParameters['createdBy'] != null) { @@ -283,12 +283,12 @@ export class QueueOperationsApi extends runtime.BaseAPI { queryParameters['sortOrder'] = requestParameters['sortOrder']; } - if (requestParameters['page'] != null) { - queryParameters['page'] = requestParameters['page']; + if (requestParameters['createdAtFrom'] != null) { + queryParameters['createdAtFrom'] = requestParameters['createdAtFrom']; } - if (requestParameters['pageSize'] != null) { - queryParameters['pageSize'] = requestParameters['pageSize']; + if (requestParameters['createdAtTo'] != null) { + queryParameters['createdAtTo'] = requestParameters['createdAtTo']; } const headerParameters: runtime.HTTPHeaders = {}; @@ -501,7 +501,6 @@ export class QueueOperationsApi extends runtime.BaseAPI { export const QueueOperationsControllerGetDeploymentQueueV1StatusesEnum = { Pending: 'PENDING', Ready: 'READY', - Executing: 'EXECUTING', Executed: 'EXECUTED', Failed: 'FAILED', Cancelled: 'CANCELLED' @@ -513,7 +512,8 @@ export type QueueOperationsControllerGetDeploymentQueueV1StatusesEnum = typeof Q export const QueueOperationsControllerGetDeploymentQueueV1OperationTypesEnum = { MultisigConfigChange: 'MULTISIG_CONFIG_CHANGE', Reject: 'REJECT', - Payout: 'PAYOUT' + Payout: 'PAYOUT', + DappTransaction: 'DAPP_TRANSACTION' } as const; export type QueueOperationsControllerGetDeploymentQueueV1OperationTypesEnum = typeof QueueOperationsControllerGetDeploymentQueueV1OperationTypesEnum[keyof typeof QueueOperationsControllerGetDeploymentQueueV1OperationTypesEnum]; /** diff --git a/generated-contracts/apis/transactions-api.ts b/generated-contracts/apis/transactions-api.ts index 2092b8e..a368275 100644 --- a/generated-contracts/apis/transactions-api.ts +++ b/generated-contracts/apis/transactions-api.ts @@ -240,7 +240,8 @@ export const TransactionsControllerGetTransactionsV1OperationTypesEnum = { SetConfig: 'set_config', Claim: 'claim', Payout: 'payout', - Reject: 'reject' + Reject: 'reject', + DappTransaction: 'dapp_transaction' } as const; export type TransactionsControllerGetTransactionsV1OperationTypesEnum = typeof TransactionsControllerGetTransactionsV1OperationTypesEnum[keyof typeof TransactionsControllerGetTransactionsV1OperationTypesEnum]; /** diff --git a/generated-contracts/models/account-currency-visibility-response-dto.ts b/generated-contracts/models/account-currency-visibility-response-dto.ts deleted file mode 100644 index 703e5b2..0000000 --- a/generated-contracts/models/account-currency-visibility-response-dto.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface AccountCurrencyVisibilityResponseDto - */ -export interface AccountCurrencyVisibilityResponseDto { - /** - * Entity unique identifier - * @type {string} - * @memberof AccountCurrencyVisibilityResponseDto - */ - accountId: string; - /** - * The unique ID of the currency, ("{chainId}-{contractAddress}") - * @type {string} - * @memberof AccountCurrencyVisibilityResponseDto - */ - currencyId: string; - /** - * Whether the currency is hidden for the current user and account - * @type {boolean} - * @memberof AccountCurrencyVisibilityResponseDto - */ - isHidden: boolean; -} - -/** - * Check if a given object implements the AccountCurrencyVisibilityResponseDto interface. - */ -export function instanceOfAccountCurrencyVisibilityResponseDto(value: object): value is AccountCurrencyVisibilityResponseDto { - if (!('accountId' in value) || value['accountId'] === undefined) return false; - if (!('currencyId' in value) || value['currencyId'] === undefined) return false; - if (!('isHidden' in value) || value['isHidden'] === undefined) return false; - return true; -} - -export function AccountCurrencyVisibilityResponseDtoFromJSON(json: any): AccountCurrencyVisibilityResponseDto { - return AccountCurrencyVisibilityResponseDtoFromJSONTyped(json, false); -} - -export function AccountCurrencyVisibilityResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AccountCurrencyVisibilityResponseDto { - if (json == null) { - return json; - } - return { - - 'accountId': json['accountId'], - 'currencyId': json['currencyId'], - 'isHidden': json['isHidden'], - }; -} - -export function AccountCurrencyVisibilityResponseDtoToJSON(json: any): AccountCurrencyVisibilityResponseDto { - return AccountCurrencyVisibilityResponseDtoToJSONTyped(json, false); -} - -export function AccountCurrencyVisibilityResponseDtoToJSONTyped(value?: AccountCurrencyVisibilityResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'accountId': value['accountId'], - 'currencyId': value['currencyId'], - 'isHidden': value['isHidden'], - }; -} - diff --git a/generated-contracts/models/address-book-entry-response-dto.ts b/generated-contracts/models/address-book-entry-response-dto.ts deleted file mode 100644 index e26a547..0000000 --- a/generated-contracts/models/address-book-entry-response-dto.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { UniversalAddress } from './universal-address'; -import { - UniversalAddressFromJSON, - UniversalAddressFromJSONTyped, - UniversalAddressToJSON, - UniversalAddressToJSONTyped, -} from './universal-address'; - -/** - * - * @export - * @interface AddressBookEntryResponseDto - */ -export interface AddressBookEntryResponseDto { - /** - * - * @type {string} - * @memberof AddressBookEntryResponseDto - */ - label: string; - /** - * - * @type {UniversalAddress} - * @memberof AddressBookEntryResponseDto - */ - address: UniversalAddress; - /** - * - * @type {boolean} - * @memberof AddressBookEntryResponseDto - */ - isTron?: boolean; - /** - * - * @type {Date} - * @memberof AddressBookEntryResponseDto - */ - createdAt: Date; - /** - * - * @type {Date} - * @memberof AddressBookEntryResponseDto - */ - updatedAt: Date; -} - -/** - * Check if a given object implements the AddressBookEntryResponseDto interface. - */ -export function instanceOfAddressBookEntryResponseDto(value: object): value is AddressBookEntryResponseDto { - if (!('label' in value) || value['label'] === undefined) return false; - if (!('address' in value) || value['address'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('updatedAt' in value) || value['updatedAt'] === undefined) return false; - return true; -} - -export function AddressBookEntryResponseDtoFromJSON(json: any): AddressBookEntryResponseDto { - return AddressBookEntryResponseDtoFromJSONTyped(json, false); -} - -export function AddressBookEntryResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AddressBookEntryResponseDto { - if (json == null) { - return json; - } - return { - - 'label': json['label'], - 'address': UniversalAddressFromJSON(json['address']), - 'isTron': json['isTron'] == null ? undefined : json['isTron'], - 'createdAt': (new Date(json['createdAt'])), - 'updatedAt': (new Date(json['updatedAt'])), - }; -} - -export function AddressBookEntryResponseDtoToJSON(json: any): AddressBookEntryResponseDto { - return AddressBookEntryResponseDtoToJSONTyped(json, false); -} - -export function AddressBookEntryResponseDtoToJSONTyped(value?: AddressBookEntryResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'label': value['label'], - 'address': UniversalAddressToJSON(value['address']), - 'isTron': value['isTron'], - 'createdAt': value['createdAt'].toISOString(), - 'updatedAt': value['updatedAt'].toISOString(), - }; -} - diff --git a/generated-contracts/models/address-book-list-response-dto-items-inner.ts b/generated-contracts/models/address-book-list-response-dto-items-inner.ts deleted file mode 100644 index 8a7e225..0000000 --- a/generated-contracts/models/address-book-list-response-dto-items-inner.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { UniversalAddress } from './universal-address'; -import { - UniversalAddressFromJSON, - UniversalAddressFromJSONTyped, - UniversalAddressToJSON, - UniversalAddressToJSONTyped, -} from './universal-address'; - -/** - * - * @export - * @interface AddressBookListResponseDtoItemsInner - */ -export interface AddressBookListResponseDtoItemsInner { - /** - * - * @type {string} - * @memberof AddressBookListResponseDtoItemsInner - */ - label: string; - /** - * - * @type {UniversalAddress} - * @memberof AddressBookListResponseDtoItemsInner - */ - address: UniversalAddress; - /** - * - * @type {boolean} - * @memberof AddressBookListResponseDtoItemsInner - */ - isTron?: boolean; - /** - * - * @type {Date} - * @memberof AddressBookListResponseDtoItemsInner - */ - createdAt: Date; - /** - * - * @type {Date} - * @memberof AddressBookListResponseDtoItemsInner - */ - updatedAt: Date; -} - -/** - * Check if a given object implements the AddressBookListResponseDtoItemsInner interface. - */ -export function instanceOfAddressBookListResponseDtoItemsInner(value: object): value is AddressBookListResponseDtoItemsInner { - if (!('label' in value) || value['label'] === undefined) return false; - if (!('address' in value) || value['address'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('updatedAt' in value) || value['updatedAt'] === undefined) return false; - return true; -} - -export function AddressBookListResponseDtoItemsInnerFromJSON(json: any): AddressBookListResponseDtoItemsInner { - return AddressBookListResponseDtoItemsInnerFromJSONTyped(json, false); -} - -export function AddressBookListResponseDtoItemsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): AddressBookListResponseDtoItemsInner { - if (json == null) { - return json; - } - return { - - 'label': json['label'], - 'address': UniversalAddressFromJSON(json['address']), - 'isTron': json['isTron'] == null ? undefined : json['isTron'], - 'createdAt': (new Date(json['createdAt'])), - 'updatedAt': (new Date(json['updatedAt'])), - }; -} - -export function AddressBookListResponseDtoItemsInnerToJSON(json: any): AddressBookListResponseDtoItemsInner { - return AddressBookListResponseDtoItemsInnerToJSONTyped(json, false); -} - -export function AddressBookListResponseDtoItemsInnerToJSONTyped(value?: AddressBookListResponseDtoItemsInner | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'label': value['label'], - 'address': UniversalAddressToJSON(value['address']), - 'isTron': value['isTron'], - 'createdAt': value['createdAt'].toISOString(), - 'updatedAt': value['updatedAt'].toISOString(), - }; -} - diff --git a/generated-contracts/models/address-book-list-response-dto.ts b/generated-contracts/models/address-book-list-response-dto.ts deleted file mode 100644 index c1f35bc..0000000 --- a/generated-contracts/models/address-book-list-response-dto.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { AddressBookListResponseDtoItemsInner } from './address-book-list-response-dto-items-inner'; -import { - AddressBookListResponseDtoItemsInnerFromJSON, - AddressBookListResponseDtoItemsInnerFromJSONTyped, - AddressBookListResponseDtoItemsInnerToJSON, - AddressBookListResponseDtoItemsInnerToJSONTyped, -} from './address-book-list-response-dto-items-inner'; - -/** - * - * @export - * @interface AddressBookListResponseDto - */ -export interface AddressBookListResponseDto { - /** - * - * @type {number} - * @memberof AddressBookListResponseDto - */ - total: number; - /** - * - * @type {number} - * @memberof AddressBookListResponseDto - */ - page: number; - /** - * - * @type {number} - * @memberof AddressBookListResponseDto - */ - pageSize: number; - /** - * - * @type {Array} - * @memberof AddressBookListResponseDto - */ - items: Array; -} - -/** - * Check if a given object implements the AddressBookListResponseDto interface. - */ -export function instanceOfAddressBookListResponseDto(value: object): value is AddressBookListResponseDto { - if (!('total' in value) || value['total'] === undefined) return false; - if (!('page' in value) || value['page'] === undefined) return false; - if (!('pageSize' in value) || value['pageSize'] === undefined) return false; - if (!('items' in value) || value['items'] === undefined) return false; - return true; -} - -export function AddressBookListResponseDtoFromJSON(json: any): AddressBookListResponseDto { - return AddressBookListResponseDtoFromJSONTyped(json, false); -} - -export function AddressBookListResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AddressBookListResponseDto { - if (json == null) { - return json; - } - return { - - 'total': json['total'], - 'page': json['page'], - 'pageSize': json['pageSize'], - 'items': ((json['items'] as Array).map(AddressBookListResponseDtoItemsInnerFromJSON)), - }; -} - -export function AddressBookListResponseDtoToJSON(json: any): AddressBookListResponseDto { - return AddressBookListResponseDtoToJSONTyped(json, false); -} - -export function AddressBookListResponseDtoToJSONTyped(value?: AddressBookListResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'total': value['total'], - 'page': value['page'], - 'pageSize': value['pageSize'], - 'items': ((value['items'] as Array).map(AddressBookListResponseDtoItemsInnerToJSON)), - }; -} - diff --git a/generated-contracts/models/api-key-list-response-dto-items-inner.ts b/generated-contracts/models/api-key-list-response-dto-items-inner.ts deleted file mode 100644 index 55973f4..0000000 --- a/generated-contracts/models/api-key-list-response-dto-items-inner.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface ApiKeyListResponseDtoItemsInner - */ -export interface ApiKeyListResponseDtoItemsInner { - /** - * - * @type {string} - * @memberof ApiKeyListResponseDtoItemsInner - */ - id: string; - /** - * Deprecated: use accountId instead - * @type {string} - * @memberof ApiKeyListResponseDtoItemsInner - */ - teamId: string; - /** - * Account ID (alias of teamId) - * @type {string} - * @memberof ApiKeyListResponseDtoItemsInner - */ - accountId: string; - /** - * - * @type {string} - * @memberof ApiKeyListResponseDtoItemsInner - */ - name?: string | null; - /** - * - * @type {string} - * @memberof ApiKeyListResponseDtoItemsInner - */ - apiKeyMask: string; - /** - * - * @type {Date} - * @memberof ApiKeyListResponseDtoItemsInner - */ - createdAt: Date; - /** - * - * @type {Date} - * @memberof ApiKeyListResponseDtoItemsInner - */ - revokedAt: Date | null; -} - -/** - * Check if a given object implements the ApiKeyListResponseDtoItemsInner interface. - */ -export function instanceOfApiKeyListResponseDtoItemsInner(value: object): value is ApiKeyListResponseDtoItemsInner { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('teamId' in value) || value['teamId'] === undefined) return false; - if (!('accountId' in value) || value['accountId'] === undefined) return false; - if (!('apiKeyMask' in value) || value['apiKeyMask'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('revokedAt' in value) || value['revokedAt'] === undefined) return false; - return true; -} - -export function ApiKeyListResponseDtoItemsInnerFromJSON(json: any): ApiKeyListResponseDtoItemsInner { - return ApiKeyListResponseDtoItemsInnerFromJSONTyped(json, false); -} - -export function ApiKeyListResponseDtoItemsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): ApiKeyListResponseDtoItemsInner { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'teamId': json['teamId'], - 'accountId': json['accountId'], - 'name': json['name'] == null ? undefined : json['name'], - 'apiKeyMask': json['apiKeyMask'], - 'createdAt': (new Date(json['createdAt'])), - 'revokedAt': (json['revokedAt'] == null ? null : new Date(json['revokedAt'])), - }; -} - -export function ApiKeyListResponseDtoItemsInnerToJSON(json: any): ApiKeyListResponseDtoItemsInner { - return ApiKeyListResponseDtoItemsInnerToJSONTyped(json, false); -} - -export function ApiKeyListResponseDtoItemsInnerToJSONTyped(value?: ApiKeyListResponseDtoItemsInner | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'teamId': value['teamId'], - 'accountId': value['accountId'], - 'name': value['name'], - 'apiKeyMask': value['apiKeyMask'], - 'createdAt': value['createdAt'].toISOString(), - 'revokedAt': value['revokedAt'] == null ? value['revokedAt'] : value['revokedAt'].toISOString(), - }; -} - diff --git a/generated-contracts/models/api-key-list-response-dto.ts b/generated-contracts/models/api-key-list-response-dto.ts deleted file mode 100644 index 8a721a0..0000000 --- a/generated-contracts/models/api-key-list-response-dto.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { ApiKeyListResponseDtoItemsInner } from './api-key-list-response-dto-items-inner'; -import { - ApiKeyListResponseDtoItemsInnerFromJSON, - ApiKeyListResponseDtoItemsInnerFromJSONTyped, - ApiKeyListResponseDtoItemsInnerToJSON, - ApiKeyListResponseDtoItemsInnerToJSONTyped, -} from './api-key-list-response-dto-items-inner'; - -/** - * - * @export - * @interface ApiKeyListResponseDto - */ -export interface ApiKeyListResponseDto { - /** - * - * @type {number} - * @memberof ApiKeyListResponseDto - */ - total: number; - /** - * - * @type {number} - * @memberof ApiKeyListResponseDto - */ - page: number; - /** - * - * @type {number} - * @memberof ApiKeyListResponseDto - */ - pageSize: number; - /** - * - * @type {Array} - * @memberof ApiKeyListResponseDto - */ - items: Array; -} - -/** - * Check if a given object implements the ApiKeyListResponseDto interface. - */ -export function instanceOfApiKeyListResponseDto(value: object): value is ApiKeyListResponseDto { - if (!('total' in value) || value['total'] === undefined) return false; - if (!('page' in value) || value['page'] === undefined) return false; - if (!('pageSize' in value) || value['pageSize'] === undefined) return false; - if (!('items' in value) || value['items'] === undefined) return false; - return true; -} - -export function ApiKeyListResponseDtoFromJSON(json: any): ApiKeyListResponseDto { - return ApiKeyListResponseDtoFromJSONTyped(json, false); -} - -export function ApiKeyListResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ApiKeyListResponseDto { - if (json == null) { - return json; - } - return { - - 'total': json['total'], - 'page': json['page'], - 'pageSize': json['pageSize'], - 'items': ((json['items'] as Array).map(ApiKeyListResponseDtoItemsInnerFromJSON)), - }; -} - -export function ApiKeyListResponseDtoToJSON(json: any): ApiKeyListResponseDto { - return ApiKeyListResponseDtoToJSONTyped(json, false); -} - -export function ApiKeyListResponseDtoToJSONTyped(value?: ApiKeyListResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'total': value['total'], - 'page': value['page'], - 'pageSize': value['pageSize'], - 'items': ((value['items'] as Array).map(ApiKeyListResponseDtoItemsInnerToJSON)), - }; -} - diff --git a/generated-contracts/models/api-key-meta-dto.ts b/generated-contracts/models/api-key-meta-dto.ts deleted file mode 100644 index b6c4c52..0000000 --- a/generated-contracts/models/api-key-meta-dto.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface ApiKeyMetaDto - */ -export interface ApiKeyMetaDto { - /** - * - * @type {string} - * @memberof ApiKeyMetaDto - */ - id: string; - /** - * Deprecated: use accountId instead - * @type {string} - * @memberof ApiKeyMetaDto - */ - teamId: string; - /** - * Account ID (alias of teamId) - * @type {string} - * @memberof ApiKeyMetaDto - */ - accountId: string; - /** - * - * @type {string} - * @memberof ApiKeyMetaDto - */ - name?: string | null; - /** - * - * @type {string} - * @memberof ApiKeyMetaDto - */ - apiKeyMask: string; - /** - * - * @type {Date} - * @memberof ApiKeyMetaDto - */ - createdAt: Date; - /** - * - * @type {Date} - * @memberof ApiKeyMetaDto - */ - revokedAt: Date | null; -} - -/** - * Check if a given object implements the ApiKeyMetaDto interface. - */ -export function instanceOfApiKeyMetaDto(value: object): value is ApiKeyMetaDto { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('teamId' in value) || value['teamId'] === undefined) return false; - if (!('accountId' in value) || value['accountId'] === undefined) return false; - if (!('apiKeyMask' in value) || value['apiKeyMask'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('revokedAt' in value) || value['revokedAt'] === undefined) return false; - return true; -} - -export function ApiKeyMetaDtoFromJSON(json: any): ApiKeyMetaDto { - return ApiKeyMetaDtoFromJSONTyped(json, false); -} - -export function ApiKeyMetaDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ApiKeyMetaDto { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'teamId': json['teamId'], - 'accountId': json['accountId'], - 'name': json['name'] == null ? undefined : json['name'], - 'apiKeyMask': json['apiKeyMask'], - 'createdAt': (new Date(json['createdAt'])), - 'revokedAt': (json['revokedAt'] == null ? null : new Date(json['revokedAt'])), - }; -} - -export function ApiKeyMetaDtoToJSON(json: any): ApiKeyMetaDto { - return ApiKeyMetaDtoToJSONTyped(json, false); -} - -export function ApiKeyMetaDtoToJSONTyped(value?: ApiKeyMetaDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'teamId': value['teamId'], - 'accountId': value['accountId'], - 'name': value['name'], - 'apiKeyMask': value['apiKeyMask'], - 'createdAt': value['createdAt'].toISOString(), - 'revokedAt': value['revokedAt'] == null ? value['revokedAt'] : value['revokedAt'].toISOString(), - }; -} - diff --git a/generated-contracts/models/asset-balance-dto.ts b/generated-contracts/models/asset-balance-dto.ts index 09f99f2..ac4ed10 100644 --- a/generated-contracts/models/asset-balance-dto.ts +++ b/generated-contracts/models/asset-balance-dto.ts @@ -28,7 +28,7 @@ import { */ export interface AssetBalanceDto { /** - * Asset currency information + * * @type {CurrencyResponseDto} * @memberof AssetBalanceDto */ diff --git a/generated-contracts/models/asset-balance-short-response-dto.ts b/generated-contracts/models/asset-balance-short-response-dto.ts new file mode 100644 index 0000000..624f4c6 --- /dev/null +++ b/generated-contracts/models/asset-balance-short-response-dto.ts @@ -0,0 +1,91 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * DeFi API (API users) + * API surface available via API key authentication + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { CurrencyResponseDto } from './currency-response-dto'; +import { + CurrencyResponseDtoFromJSON, + CurrencyResponseDtoFromJSONTyped, + CurrencyResponseDtoToJSON, + CurrencyResponseDtoToJSONTyped, +} from './currency-response-dto'; + +/** + * + * @export + * @interface AssetBalanceShortResponseDto + */ +export interface AssetBalanceShortResponseDto { + /** + * + * @type {CurrencyResponseDto} + * @memberof AssetBalanceShortResponseDto + */ + currency: CurrencyResponseDto; + /** + * Asset balance + * @type {number} + * @memberof AssetBalanceShortResponseDto + */ + balance: number; + /** + * Only for JWT users; ignored for API keys + * @type {boolean} + * @memberof AssetBalanceShortResponseDto + */ + isHidden?: boolean; +} + +/** + * Check if a given object implements the AssetBalanceShortResponseDto interface. + */ +export function instanceOfAssetBalanceShortResponseDto(value: object): value is AssetBalanceShortResponseDto { + if (!('currency' in value) || value['currency'] === undefined) return false; + if (!('balance' in value) || value['balance'] === undefined) return false; + return true; +} + +export function AssetBalanceShortResponseDtoFromJSON(json: any): AssetBalanceShortResponseDto { + return AssetBalanceShortResponseDtoFromJSONTyped(json, false); +} + +export function AssetBalanceShortResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetBalanceShortResponseDto { + if (json == null) { + return json; + } + return { + + 'currency': CurrencyResponseDtoFromJSON(json['currency']), + 'balance': json['balance'], + 'isHidden': json['isHidden'] == null ? undefined : json['isHidden'], + }; +} + +export function AssetBalanceShortResponseDtoToJSON(json: any): AssetBalanceShortResponseDto { + return AssetBalanceShortResponseDtoToJSONTyped(json, false); +} + +export function AssetBalanceShortResponseDtoToJSONTyped(value?: AssetBalanceShortResponseDto | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'currency': CurrencyResponseDtoToJSON(value['currency']), + 'balance': value['balance'], + 'isHidden': value['isHidden'], + }; +} + diff --git a/generated-contracts/models/asset-balances-response-dto.ts b/generated-contracts/models/asset-balances-response-dto.ts index d0ea754..13fbb19 100644 --- a/generated-contracts/models/asset-balances-response-dto.ts +++ b/generated-contracts/models/asset-balances-response-dto.ts @@ -46,7 +46,7 @@ export interface AssetBalancesResponseDto { */ pageSize: number; /** - * List of asset balances + * * @type {Array} * @memberof AssetBalancesResponseDto */ diff --git a/generated-contracts/models/auth-response-dto.ts b/generated-contracts/models/auth-response-dto.ts deleted file mode 100644 index ffbc95b..0000000 --- a/generated-contracts/models/auth-response-dto.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { UserResponseDto } from './user-response-dto'; -import { - UserResponseDtoFromJSON, - UserResponseDtoFromJSONTyped, - UserResponseDtoToJSON, - UserResponseDtoToJSONTyped, -} from './user-response-dto'; - -/** - * - * @export - * @interface AuthResponseDto - */ -export interface AuthResponseDto { - /** - * JWT access token - * @type {string} - * @memberof AuthResponseDto - */ - accessToken: string; - /** - * JWT refresh token - * @type {string} - * @memberof AuthResponseDto - */ - refreshToken: string; - /** - * Token expiration timestamp - * @type {string} - * @memberof AuthResponseDto - */ - expiresAt: string; - /** - * User information - * @type {UserResponseDto} - * @memberof AuthResponseDto - */ - user: UserResponseDto; -} - -/** - * Check if a given object implements the AuthResponseDto interface. - */ -export function instanceOfAuthResponseDto(value: object): value is AuthResponseDto { - if (!('accessToken' in value) || value['accessToken'] === undefined) return false; - if (!('refreshToken' in value) || value['refreshToken'] === undefined) return false; - if (!('expiresAt' in value) || value['expiresAt'] === undefined) return false; - if (!('user' in value) || value['user'] === undefined) return false; - return true; -} - -export function AuthResponseDtoFromJSON(json: any): AuthResponseDto { - return AuthResponseDtoFromJSONTyped(json, false); -} - -export function AuthResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AuthResponseDto { - if (json == null) { - return json; - } - return { - - 'accessToken': json['accessToken'], - 'refreshToken': json['refreshToken'], - 'expiresAt': json['expiresAt'], - 'user': UserResponseDtoFromJSON(json['user']), - }; -} - -export function AuthResponseDtoToJSON(json: any): AuthResponseDto { - return AuthResponseDtoToJSONTyped(json, false); -} - -export function AuthResponseDtoToJSONTyped(value?: AuthResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'accessToken': value['accessToken'], - 'refreshToken': value['refreshToken'], - 'expiresAt': value['expiresAt'], - 'user': UserResponseDtoToJSON(value['user']), - }; -} - diff --git a/generated-contracts/models/balance-history-response-dto-items-inner.ts b/generated-contracts/models/balance-history-response-dto-items-inner.ts deleted file mode 100644 index cb9663d..0000000 --- a/generated-contracts/models/balance-history-response-dto-items-inner.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface BalanceHistoryResponseDtoItemsInner - */ -export interface BalanceHistoryResponseDtoItemsInner { - /** - * - * @type {string} - * @memberof BalanceHistoryResponseDtoItemsInner - */ - balance: string; - /** - * - * @type {Date} - * @memberof BalanceHistoryResponseDtoItemsInner - */ - timestamp: Date; -} - -/** - * Check if a given object implements the BalanceHistoryResponseDtoItemsInner interface. - */ -export function instanceOfBalanceHistoryResponseDtoItemsInner(value: object): value is BalanceHistoryResponseDtoItemsInner { - if (!('balance' in value) || value['balance'] === undefined) return false; - if (!('timestamp' in value) || value['timestamp'] === undefined) return false; - return true; -} - -export function BalanceHistoryResponseDtoItemsInnerFromJSON(json: any): BalanceHistoryResponseDtoItemsInner { - return BalanceHistoryResponseDtoItemsInnerFromJSONTyped(json, false); -} - -export function BalanceHistoryResponseDtoItemsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): BalanceHistoryResponseDtoItemsInner { - if (json == null) { - return json; - } - return { - - 'balance': json['balance'], - 'timestamp': (new Date(json['timestamp'])), - }; -} - -export function BalanceHistoryResponseDtoItemsInnerToJSON(json: any): BalanceHistoryResponseDtoItemsInner { - return BalanceHistoryResponseDtoItemsInnerToJSONTyped(json, false); -} - -export function BalanceHistoryResponseDtoItemsInnerToJSONTyped(value?: BalanceHistoryResponseDtoItemsInner | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'balance': value['balance'], - 'timestamp': value['timestamp'].toISOString(), - }; -} - diff --git a/generated-contracts/models/balance-history-response-dto.ts b/generated-contracts/models/balance-history-response-dto.ts deleted file mode 100644 index bf7c146..0000000 --- a/generated-contracts/models/balance-history-response-dto.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { BalanceHistoryResponseDtoItemsInner } from './balance-history-response-dto-items-inner'; -import { - BalanceHistoryResponseDtoItemsInnerFromJSON, - BalanceHistoryResponseDtoItemsInnerFromJSONTyped, - BalanceHistoryResponseDtoItemsInnerToJSON, - BalanceHistoryResponseDtoItemsInnerToJSONTyped, -} from './balance-history-response-dto-items-inner'; - -/** - * - * @export - * @interface BalanceHistoryResponseDto - */ -export interface BalanceHistoryResponseDto { - /** - * - * @type {Array} - * @memberof BalanceHistoryResponseDto - */ - items: Array; -} - -/** - * Check if a given object implements the BalanceHistoryResponseDto interface. - */ -export function instanceOfBalanceHistoryResponseDto(value: object): value is BalanceHistoryResponseDto { - if (!('items' in value) || value['items'] === undefined) return false; - return true; -} - -export function BalanceHistoryResponseDtoFromJSON(json: any): BalanceHistoryResponseDto { - return BalanceHistoryResponseDtoFromJSONTyped(json, false); -} - -export function BalanceHistoryResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): BalanceHistoryResponseDto { - if (json == null) { - return json; - } - return { - - 'items': ((json['items'] as Array).map(BalanceHistoryResponseDtoItemsInnerFromJSON)), - }; -} - -export function BalanceHistoryResponseDtoToJSON(json: any): BalanceHistoryResponseDto { - return BalanceHistoryResponseDtoToJSONTyped(json, false); -} - -export function BalanceHistoryResponseDtoToJSONTyped(value?: BalanceHistoryResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'items': ((value['items'] as Array).map(BalanceHistoryResponseDtoItemsInnerToJSON)), - }; -} - diff --git a/generated-contracts/models/callback-secret-response-dto.ts b/generated-contracts/models/callback-secret-response-dto.ts deleted file mode 100644 index b8293a1..0000000 --- a/generated-contracts/models/callback-secret-response-dto.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface CallbackSecretResponseDto - */ -export interface CallbackSecretResponseDto { - /** - * Generated callback secret for HMAC signing (shown only once) - * @type {string} - * @memberof CallbackSecretResponseDto - */ - secret: string; -} - -/** - * Check if a given object implements the CallbackSecretResponseDto interface. - */ -export function instanceOfCallbackSecretResponseDto(value: object): value is CallbackSecretResponseDto { - if (!('secret' in value) || value['secret'] === undefined) return false; - return true; -} - -export function CallbackSecretResponseDtoFromJSON(json: any): CallbackSecretResponseDto { - return CallbackSecretResponseDtoFromJSONTyped(json, false); -} - -export function CallbackSecretResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CallbackSecretResponseDto { - if (json == null) { - return json; - } - return { - - 'secret': json['secret'], - }; -} - -export function CallbackSecretResponseDtoToJSON(json: any): CallbackSecretResponseDto { - return CallbackSecretResponseDtoToJSONTyped(json, false); -} - -export function CallbackSecretResponseDtoToJSONTyped(value?: CallbackSecretResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'secret': value['secret'], - }; -} - diff --git a/generated-contracts/models/create-account-dto.ts b/generated-contracts/models/create-account-dto.ts deleted file mode 100644 index 138e37b..0000000 --- a/generated-contracts/models/create-account-dto.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { UniversalAddress } from './universal-address'; -import { - UniversalAddressFromJSON, - UniversalAddressFromJSONTyped, - UniversalAddressToJSON, - UniversalAddressToJSONTyped, -} from './universal-address'; - -/** - * - * @export - * @interface CreateAccountDto - */ -export interface CreateAccountDto { - /** - * - * @type {string} - * @memberof CreateAccountDto - */ - name: string; - /** - * - * @type {number} - * @memberof CreateAccountDto - */ - threshold: number; - /** - * - * @type {Array} - * @memberof CreateAccountDto - */ - approvers: Array; - /** - * - * @type {boolean} - * @memberof CreateAccountDto - */ - isTron?: boolean; - /** - * Chain ID - * @type {string} - * @memberof CreateAccountDto - */ - networkId?: string; -} - -/** - * Check if a given object implements the CreateAccountDto interface. - */ -export function instanceOfCreateAccountDto(value: object): value is CreateAccountDto { - if (!('name' in value) || value['name'] === undefined) return false; - if (!('threshold' in value) || value['threshold'] === undefined) return false; - if (!('approvers' in value) || value['approvers'] === undefined) return false; - return true; -} - -export function CreateAccountDtoFromJSON(json: any): CreateAccountDto { - return CreateAccountDtoFromJSONTyped(json, false); -} - -export function CreateAccountDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateAccountDto { - if (json == null) { - return json; - } - return { - - 'name': json['name'], - 'threshold': json['threshold'], - 'approvers': ((json['approvers'] as Array).map(UniversalAddressFromJSON)), - 'isTron': json['isTron'] == null ? undefined : json['isTron'], - 'networkId': json['networkId'] == null ? undefined : json['networkId'], - }; -} - -export function CreateAccountDtoToJSON(json: any): CreateAccountDto { - return CreateAccountDtoToJSONTyped(json, false); -} - -export function CreateAccountDtoToJSONTyped(value?: CreateAccountDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'name': value['name'], - 'threshold': value['threshold'], - 'approvers': ((value['approvers'] as Array).map(UniversalAddressToJSON)), - 'isTron': value['isTron'], - 'networkId': value['networkId'], - }; -} - diff --git a/generated-contracts/models/create-address-book-entry-dto.ts b/generated-contracts/models/create-address-book-entry-dto.ts deleted file mode 100644 index c5a0f26..0000000 --- a/generated-contracts/models/create-address-book-entry-dto.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { UniversalAddress } from './universal-address'; -import { - UniversalAddressFromJSON, - UniversalAddressFromJSONTyped, - UniversalAddressToJSON, - UniversalAddressToJSONTyped, -} from './universal-address'; - -/** - * - * @export - * @interface CreateAddressBookEntryDto - */ -export interface CreateAddressBookEntryDto { - /** - * - * @type {string} - * @memberof CreateAddressBookEntryDto - */ - label: string; - /** - * - * @type {UniversalAddress} - * @memberof CreateAddressBookEntryDto - */ - address: UniversalAddress; -} - -/** - * Check if a given object implements the CreateAddressBookEntryDto interface. - */ -export function instanceOfCreateAddressBookEntryDto(value: object): value is CreateAddressBookEntryDto { - if (!('label' in value) || value['label'] === undefined) return false; - if (!('address' in value) || value['address'] === undefined) return false; - return true; -} - -export function CreateAddressBookEntryDtoFromJSON(json: any): CreateAddressBookEntryDto { - return CreateAddressBookEntryDtoFromJSONTyped(json, false); -} - -export function CreateAddressBookEntryDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateAddressBookEntryDto { - if (json == null) { - return json; - } - return { - - 'label': json['label'], - 'address': UniversalAddressFromJSON(json['address']), - }; -} - -export function CreateAddressBookEntryDtoToJSON(json: any): CreateAddressBookEntryDto { - return CreateAddressBookEntryDtoToJSONTyped(json, false); -} - -export function CreateAddressBookEntryDtoToJSONTyped(value?: CreateAddressBookEntryDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'label': value['label'], - 'address': UniversalAddressToJSON(value['address']), - }; -} - diff --git a/generated-contracts/models/create-api-key-dto.ts b/generated-contracts/models/create-api-key-dto.ts deleted file mode 100644 index 5f6f412..0000000 --- a/generated-contracts/models/create-api-key-dto.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface CreateApiKeyDto - */ -export interface CreateApiKeyDto { - /** - * - * @type {string} - * @memberof CreateApiKeyDto - */ - name?: string | null; -} - -/** - * Check if a given object implements the CreateApiKeyDto interface. - */ -export function instanceOfCreateApiKeyDto(value: object): value is CreateApiKeyDto { - return true; -} - -export function CreateApiKeyDtoFromJSON(json: any): CreateApiKeyDto { - return CreateApiKeyDtoFromJSONTyped(json, false); -} - -export function CreateApiKeyDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateApiKeyDto { - if (json == null) { - return json; - } - return { - - 'name': json['name'] == null ? undefined : json['name'], - }; -} - -export function CreateApiKeyDtoToJSON(json: any): CreateApiKeyDto { - return CreateApiKeyDtoToJSONTyped(json, false); -} - -export function CreateApiKeyDtoToJSONTyped(value?: CreateApiKeyDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'name': value['name'], - }; -} - diff --git a/generated-contracts/models/create-api-key-response-dto.ts b/generated-contracts/models/create-api-key-response-dto.ts deleted file mode 100644 index b110777..0000000 --- a/generated-contracts/models/create-api-key-response-dto.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface CreateApiKeyResponseDto - */ -export interface CreateApiKeyResponseDto { - /** - * - * @type {string} - * @memberof CreateApiKeyResponseDto - */ - id: string; - /** - * Deprecated: use accountId instead - * @type {string} - * @memberof CreateApiKeyResponseDto - */ - teamId: string; - /** - * Account ID (alias of teamId) - * @type {string} - * @memberof CreateApiKeyResponseDto - */ - accountId: string; - /** - * - * @type {string} - * @memberof CreateApiKeyResponseDto - */ - name?: string | null; - /** - * - * @type {string} - * @memberof CreateApiKeyResponseDto - */ - apiKeyMask: string; - /** - * - * @type {Date} - * @memberof CreateApiKeyResponseDto - */ - createdAt: Date; - /** - * - * @type {Date} - * @memberof CreateApiKeyResponseDto - */ - revokedAt: Date | null; - /** - * - * @type {string} - * @memberof CreateApiKeyResponseDto - */ - apiKey: string; -} - -/** - * Check if a given object implements the CreateApiKeyResponseDto interface. - */ -export function instanceOfCreateApiKeyResponseDto(value: object): value is CreateApiKeyResponseDto { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('teamId' in value) || value['teamId'] === undefined) return false; - if (!('accountId' in value) || value['accountId'] === undefined) return false; - if (!('apiKeyMask' in value) || value['apiKeyMask'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('revokedAt' in value) || value['revokedAt'] === undefined) return false; - if (!('apiKey' in value) || value['apiKey'] === undefined) return false; - return true; -} - -export function CreateApiKeyResponseDtoFromJSON(json: any): CreateApiKeyResponseDto { - return CreateApiKeyResponseDtoFromJSONTyped(json, false); -} - -export function CreateApiKeyResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateApiKeyResponseDto { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'teamId': json['teamId'], - 'accountId': json['accountId'], - 'name': json['name'] == null ? undefined : json['name'], - 'apiKeyMask': json['apiKeyMask'], - 'createdAt': (new Date(json['createdAt'])), - 'revokedAt': (json['revokedAt'] == null ? null : new Date(json['revokedAt'])), - 'apiKey': json['apiKey'], - }; -} - -export function CreateApiKeyResponseDtoToJSON(json: any): CreateApiKeyResponseDto { - return CreateApiKeyResponseDtoToJSONTyped(json, false); -} - -export function CreateApiKeyResponseDtoToJSONTyped(value?: CreateApiKeyResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'teamId': value['teamId'], - 'accountId': value['accountId'], - 'name': value['name'], - 'apiKeyMask': value['apiKeyMask'], - 'createdAt': value['createdAt'].toISOString(), - 'revokedAt': value['revokedAt'] == null ? value['revokedAt'] : value['revokedAt'].toISOString(), - 'apiKey': value['apiKey'], - }; -} - diff --git a/generated-contracts/models/create-multisig-config-change-operation-dto-calls-inner.ts b/generated-contracts/models/create-multisig-config-change-operation-dto-calls-inner.ts deleted file mode 100644 index 2933f69..0000000 --- a/generated-contracts/models/create-multisig-config-change-operation-dto-calls-inner.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface CreateMultisigConfigChangeOperationDtoCallsInner - */ -export interface CreateMultisigConfigChangeOperationDtoCallsInner { - /** - * Ethereum address in lowercase format - * @type {string} - * @memberof CreateMultisigConfigChangeOperationDtoCallsInner - */ - to: string; - /** - * - * @type {string} - * @memberof CreateMultisigConfigChangeOperationDtoCallsInner - */ - value: string; - /** - * - * @type {string} - * @memberof CreateMultisigConfigChangeOperationDtoCallsInner - */ - data: string; -} - -/** - * Check if a given object implements the CreateMultisigConfigChangeOperationDtoCallsInner interface. - */ -export function instanceOfCreateMultisigConfigChangeOperationDtoCallsInner(value: object): value is CreateMultisigConfigChangeOperationDtoCallsInner { - if (!('to' in value) || value['to'] === undefined) return false; - if (!('value' in value) || value['value'] === undefined) return false; - if (!('data' in value) || value['data'] === undefined) return false; - return true; -} - -export function CreateMultisigConfigChangeOperationDtoCallsInnerFromJSON(json: any): CreateMultisigConfigChangeOperationDtoCallsInner { - return CreateMultisigConfigChangeOperationDtoCallsInnerFromJSONTyped(json, false); -} - -export function CreateMultisigConfigChangeOperationDtoCallsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateMultisigConfigChangeOperationDtoCallsInner { - if (json == null) { - return json; - } - return { - - 'to': json['to'], - 'value': json['value'], - 'data': json['data'], - }; -} - -export function CreateMultisigConfigChangeOperationDtoCallsInnerToJSON(json: any): CreateMultisigConfigChangeOperationDtoCallsInner { - return CreateMultisigConfigChangeOperationDtoCallsInnerToJSONTyped(json, false); -} - -export function CreateMultisigConfigChangeOperationDtoCallsInnerToJSONTyped(value?: CreateMultisigConfigChangeOperationDtoCallsInner | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'to': value['to'], - 'value': value['value'], - 'data': value['data'], - }; -} - diff --git a/generated-contracts/models/create-multisig-config-change-operation-dto.ts b/generated-contracts/models/create-multisig-config-change-operation-dto.ts index 3836366..065415f 100644 --- a/generated-contracts/models/create-multisig-config-change-operation-dto.ts +++ b/generated-contracts/models/create-multisig-config-change-operation-dto.ts @@ -13,13 +13,6 @@ */ import { mapValues } from '../runtime'; -import type { CreateMultisigConfigChangeOperationDtoCallsInner } from './create-multisig-config-change-operation-dto-calls-inner'; -import { - CreateMultisigConfigChangeOperationDtoCallsInnerFromJSON, - CreateMultisigConfigChangeOperationDtoCallsInnerFromJSONTyped, - CreateMultisigConfigChangeOperationDtoCallsInnerToJSON, - CreateMultisigConfigChangeOperationDtoCallsInnerToJSONTyped, -} from './create-multisig-config-change-operation-dto-calls-inner'; import type { UniversalAddress } from './universal-address'; import { UniversalAddressFromJSON, @@ -27,6 +20,13 @@ import { UniversalAddressToJSON, UniversalAddressToJSONTyped, } from './universal-address'; +import type { CallDto } from './call-dto'; +import { + CallDtoFromJSON, + CallDtoFromJSONTyped, + CallDtoToJSON, + CallDtoToJSONTyped, +} from './call-dto'; /** * @@ -48,10 +48,10 @@ export interface CreateMultisigConfigChangeOperationDto { threshold: number; /** * - * @type {Array} + * @type {Array} * @memberof CreateMultisigConfigChangeOperationDto */ - calls: Array; + calls: Array; } /** @@ -76,7 +76,7 @@ export function CreateMultisigConfigChangeOperationDtoFromJSONTyped(json: any, i 'approvers': ((json['approvers'] as Array).map(UniversalAddressFromJSON)), 'threshold': json['threshold'], - 'calls': ((json['calls'] as Array).map(CreateMultisigConfigChangeOperationDtoCallsInnerFromJSON)), + 'calls': ((json['calls'] as Array).map(CallDtoFromJSON)), }; } @@ -93,7 +93,7 @@ export function CreateMultisigConfigChangeOperationDtoToJSONTyped(value?: Create 'approvers': ((value['approvers'] as Array).map(UniversalAddressToJSON)), 'threshold': value['threshold'], - 'calls': ((value['calls'] as Array).map(CreateMultisigConfigChangeOperationDtoCallsInnerToJSON)), + 'calls': ((value['calls'] as Array).map(CallDtoToJSON)), }; } diff --git a/generated-contracts/models/create-payment-body-dto.ts b/generated-contracts/models/create-payment-body-dto.ts deleted file mode 100644 index 839955a..0000000 --- a/generated-contracts/models/create-payment-body-dto.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface CreatePaymentBodyDto - */ -export interface CreatePaymentBodyDto { - /** - * Currency ID for top-up - * @type {string} - * @memberof CreatePaymentBodyDto - */ - currencyId: string; -} - -/** - * Check if a given object implements the CreatePaymentBodyDto interface. - */ -export function instanceOfCreatePaymentBodyDto(value: object): value is CreatePaymentBodyDto { - if (!('currencyId' in value) || value['currencyId'] === undefined) return false; - return true; -} - -export function CreatePaymentBodyDtoFromJSON(json: any): CreatePaymentBodyDto { - return CreatePaymentBodyDtoFromJSONTyped(json, false); -} - -export function CreatePaymentBodyDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreatePaymentBodyDto { - if (json == null) { - return json; - } - return { - - 'currencyId': json['currencyId'], - }; -} - -export function CreatePaymentBodyDtoToJSON(json: any): CreatePaymentBodyDto { - return CreatePaymentBodyDtoToJSONTyped(json, false); -} - -export function CreatePaymentBodyDtoToJSONTyped(value?: CreatePaymentBodyDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'currencyId': value['currencyId'], - }; -} - diff --git a/generated-contracts/models/create-payout-dto.ts b/generated-contracts/models/create-payout-dto.ts index 67f8278..288ed67 100644 --- a/generated-contracts/models/create-payout-dto.ts +++ b/generated-contracts/models/create-payout-dto.ts @@ -34,7 +34,7 @@ export interface CreatePayoutDto { */ deploymentId: string; /** - * + * The unique ID of the currency, ("{chainId}" or "{chainId}-{contractAddress}") * @type {string} * @memberof CreatePayoutDto */ diff --git a/generated-contracts/models/credit-price-item-dto.ts b/generated-contracts/models/credit-price-item-dto.ts deleted file mode 100644 index cd9ed36..0000000 --- a/generated-contracts/models/credit-price-item-dto.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface CreditPriceItemDto - */ -export interface CreditPriceItemDto { - /** - * Price of one credit in the specified currency - * @type {string} - * @memberof CreditPriceItemDto - */ - price: string; - /** - * Currency identifier - * @type {string} - * @memberof CreditPriceItemDto - */ - currencyId: string; -} - -/** - * Check if a given object implements the CreditPriceItemDto interface. - */ -export function instanceOfCreditPriceItemDto(value: object): value is CreditPriceItemDto { - if (!('price' in value) || value['price'] === undefined) return false; - if (!('currencyId' in value) || value['currencyId'] === undefined) return false; - return true; -} - -export function CreditPriceItemDtoFromJSON(json: any): CreditPriceItemDto { - return CreditPriceItemDtoFromJSONTyped(json, false); -} - -export function CreditPriceItemDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreditPriceItemDto { - if (json == null) { - return json; - } - return { - - 'price': json['price'], - 'currencyId': json['currencyId'], - }; -} - -export function CreditPriceItemDtoToJSON(json: any): CreditPriceItemDto { - return CreditPriceItemDtoToJSONTyped(json, false); -} - -export function CreditPriceItemDtoToJSONTyped(value?: CreditPriceItemDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'price': value['price'], - 'currencyId': value['currencyId'], - }; -} - diff --git a/generated-contracts/models/credits-overview-response-dto-unit-prices-inner-discounts-inner.ts b/generated-contracts/models/credits-overview-response-dto-unit-prices-inner-discounts-inner.ts deleted file mode 100644 index ccb9d25..0000000 --- a/generated-contracts/models/credits-overview-response-dto-unit-prices-inner-discounts-inner.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner - */ -export interface CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner { - /** - * - * @type {number} - * @memberof CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner - */ - minAmount: number; - /** - * - * @type {number} - * @memberof CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner - */ - discountPercent: number; -} - -/** - * Check if a given object implements the CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner interface. - */ -export function instanceOfCreditsOverviewResponseDtoUnitPricesInnerDiscountsInner(value: object): value is CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner { - if (!('minAmount' in value) || value['minAmount'] === undefined) return false; - if (!('discountPercent' in value) || value['discountPercent'] === undefined) return false; - return true; -} - -export function CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerFromJSON(json: any): CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner { - return CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerFromJSONTyped(json, false); -} - -export function CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner { - if (json == null) { - return json; - } - return { - - 'minAmount': json['minAmount'], - 'discountPercent': json['discountPercent'], - }; -} - -export function CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerToJSON(json: any): CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner { - return CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerToJSONTyped(json, false); -} - -export function CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerToJSONTyped(value?: CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'minAmount': value['minAmount'], - 'discountPercent': value['discountPercent'], - }; -} - diff --git a/generated-contracts/models/credits-overview-response-dto-unit-prices-inner.ts b/generated-contracts/models/credits-overview-response-dto-unit-prices-inner.ts deleted file mode 100644 index 70b00cb..0000000 --- a/generated-contracts/models/credits-overview-response-dto-unit-prices-inner.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { CreditsOverviewResponseDtoUnitPricesInnerDiscountsInner } from './credits-overview-response-dto-unit-prices-inner-discounts-inner'; -import { - CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerFromJSON, - CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerFromJSONTyped, - CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerToJSON, - CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerToJSONTyped, -} from './credits-overview-response-dto-unit-prices-inner-discounts-inner'; - -/** - * - * @export - * @interface CreditsOverviewResponseDtoUnitPricesInner - */ -export interface CreditsOverviewResponseDtoUnitPricesInner { - /** - * - * @type {string} - * @memberof CreditsOverviewResponseDtoUnitPricesInner - */ - currencyId: string; - /** - * - * @type {string} - * @memberof CreditsOverviewResponseDtoUnitPricesInner - */ - price: string; - /** - * - * @type {Array} - * @memberof CreditsOverviewResponseDtoUnitPricesInner - */ - discounts: Array; -} - -/** - * Check if a given object implements the CreditsOverviewResponseDtoUnitPricesInner interface. - */ -export function instanceOfCreditsOverviewResponseDtoUnitPricesInner(value: object): value is CreditsOverviewResponseDtoUnitPricesInner { - if (!('currencyId' in value) || value['currencyId'] === undefined) return false; - if (!('price' in value) || value['price'] === undefined) return false; - if (!('discounts' in value) || value['discounts'] === undefined) return false; - return true; -} - -export function CreditsOverviewResponseDtoUnitPricesInnerFromJSON(json: any): CreditsOverviewResponseDtoUnitPricesInner { - return CreditsOverviewResponseDtoUnitPricesInnerFromJSONTyped(json, false); -} - -export function CreditsOverviewResponseDtoUnitPricesInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreditsOverviewResponseDtoUnitPricesInner { - if (json == null) { - return json; - } - return { - - 'currencyId': json['currencyId'], - 'price': json['price'], - 'discounts': ((json['discounts'] as Array).map(CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerFromJSON)), - }; -} - -export function CreditsOverviewResponseDtoUnitPricesInnerToJSON(json: any): CreditsOverviewResponseDtoUnitPricesInner { - return CreditsOverviewResponseDtoUnitPricesInnerToJSONTyped(json, false); -} - -export function CreditsOverviewResponseDtoUnitPricesInnerToJSONTyped(value?: CreditsOverviewResponseDtoUnitPricesInner | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'currencyId': value['currencyId'], - 'price': value['price'], - 'discounts': ((value['discounts'] as Array).map(CreditsOverviewResponseDtoUnitPricesInnerDiscountsInnerToJSON)), - }; -} - diff --git a/generated-contracts/models/credits-overview-response-dto.ts b/generated-contracts/models/credits-overview-response-dto.ts deleted file mode 100644 index 77188cd..0000000 --- a/generated-contracts/models/credits-overview-response-dto.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { CreditsOverviewResponseDtoUnitPricesInner } from './credits-overview-response-dto-unit-prices-inner'; -import { - CreditsOverviewResponseDtoUnitPricesInnerFromJSON, - CreditsOverviewResponseDtoUnitPricesInnerFromJSONTyped, - CreditsOverviewResponseDtoUnitPricesInnerToJSON, - CreditsOverviewResponseDtoUnitPricesInnerToJSONTyped, -} from './credits-overview-response-dto-unit-prices-inner'; - -/** - * - * @export - * @interface CreditsOverviewResponseDto - */ -export interface CreditsOverviewResponseDto { - /** - * - * @type {number} - * @memberof CreditsOverviewResponseDto - */ - balance: number; - /** - * - * @type {number} - * @memberof CreditsOverviewResponseDto - */ - creditUsage: number; - /** - * - * @type {number} - * @memberof CreditsOverviewResponseDto - */ - creditTopUp: number; - /** - * - * @type {Array} - * @memberof CreditsOverviewResponseDto - */ - unitPrices: Array; -} - -/** - * Check if a given object implements the CreditsOverviewResponseDto interface. - */ -export function instanceOfCreditsOverviewResponseDto(value: object): value is CreditsOverviewResponseDto { - if (!('balance' in value) || value['balance'] === undefined) return false; - if (!('creditUsage' in value) || value['creditUsage'] === undefined) return false; - if (!('creditTopUp' in value) || value['creditTopUp'] === undefined) return false; - if (!('unitPrices' in value) || value['unitPrices'] === undefined) return false; - return true; -} - -export function CreditsOverviewResponseDtoFromJSON(json: any): CreditsOverviewResponseDto { - return CreditsOverviewResponseDtoFromJSONTyped(json, false); -} - -export function CreditsOverviewResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreditsOverviewResponseDto { - if (json == null) { - return json; - } - return { - - 'balance': json['balance'], - 'creditUsage': json['creditUsage'], - 'creditTopUp': json['creditTopUp'], - 'unitPrices': ((json['unitPrices'] as Array).map(CreditsOverviewResponseDtoUnitPricesInnerFromJSON)), - }; -} - -export function CreditsOverviewResponseDtoToJSON(json: any): CreditsOverviewResponseDto { - return CreditsOverviewResponseDtoToJSONTyped(json, false); -} - -export function CreditsOverviewResponseDtoToJSONTyped(value?: CreditsOverviewResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'balance': value['balance'], - 'creditUsage': value['creditUsage'], - 'creditTopUp': value['creditTopUp'], - 'unitPrices': ((value['unitPrices'] as Array).map(CreditsOverviewResponseDtoUnitPricesInnerToJSON)), - }; -} - diff --git a/generated-contracts/models/currency-response-dto.ts b/generated-contracts/models/currency-response-dto.ts index d2c2798..8837643 100644 --- a/generated-contracts/models/currency-response-dto.ts +++ b/generated-contracts/models/currency-response-dto.ts @@ -20,7 +20,7 @@ import { mapValues } from '../runtime'; */ export interface CurrencyResponseDto { /** - * The unique ID of the currency, ("{chainId}-{contractAddress}") + * The unique ID of the currency, ("{chainId}" or "{chainId}-{contractAddress}") * @type {string} * @memberof CurrencyResponseDto */ @@ -67,6 +67,12 @@ export interface CurrencyResponseDto { * @memberof CurrencyResponseDto */ isVerified: boolean; + /** + * Token logo URL from CoinMarketCap CDN + * @type {string} + * @memberof CurrencyResponseDto + */ + logoUrl: string | null; } /** @@ -81,6 +87,7 @@ export function instanceOfCurrencyResponseDto(value: object): value is CurrencyR if (!('decimals' in value) || value['decimals'] === undefined) return false; if (!('isScam' in value) || value['isScam'] === undefined) return false; if (!('isVerified' in value) || value['isVerified'] === undefined) return false; + if (!('logoUrl' in value) || value['logoUrl'] === undefined) return false; return true; } @@ -102,6 +109,7 @@ export function CurrencyResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: 'decimals': json['decimals'], 'isScam': json['isScam'], 'isVerified': json['isVerified'], + 'logoUrl': json['logoUrl'], }; } @@ -124,6 +132,7 @@ export function CurrencyResponseDtoToJSONTyped(value?: CurrencyResponseDto | nul 'decimals': value['decimals'], 'isScam': value['isScam'], 'isVerified': value['isVerified'], + 'logoUrl': value['logoUrl'], }; } diff --git a/generated-contracts/models/delete-all-operations-response-dto.ts b/generated-contracts/models/delete-all-operations-response-dto.ts deleted file mode 100644 index bc5e878..0000000 --- a/generated-contracts/models/delete-all-operations-response-dto.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface DeleteAllOperationsResponseDto - */ -export interface DeleteAllOperationsResponseDto { - /** - * Number of deleted operations - * @type {number} - * @memberof DeleteAllOperationsResponseDto - */ - deletedCount: number; -} - -/** - * Check if a given object implements the DeleteAllOperationsResponseDto interface. - */ -export function instanceOfDeleteAllOperationsResponseDto(value: object): value is DeleteAllOperationsResponseDto { - if (!('deletedCount' in value) || value['deletedCount'] === undefined) return false; - return true; -} - -export function DeleteAllOperationsResponseDtoFromJSON(json: any): DeleteAllOperationsResponseDto { - return DeleteAllOperationsResponseDtoFromJSONTyped(json, false); -} - -export function DeleteAllOperationsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): DeleteAllOperationsResponseDto { - if (json == null) { - return json; - } - return { - - 'deletedCount': json['deletedCount'], - }; -} - -export function DeleteAllOperationsResponseDtoToJSON(json: any): DeleteAllOperationsResponseDto { - return DeleteAllOperationsResponseDtoToJSONTyped(json, false); -} - -export function DeleteAllOperationsResponseDtoToJSONTyped(value?: DeleteAllOperationsResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'deletedCount': value['deletedCount'], - }; -} - diff --git a/generated-contracts/models/deployment-queue-response-dto.ts b/generated-contracts/models/deployment-queue-response-dto.ts index 540a28a..198562b 100644 --- a/generated-contracts/models/deployment-queue-response-dto.ts +++ b/generated-contracts/models/deployment-queue-response-dto.ts @@ -46,7 +46,7 @@ export interface DeploymentQueueResponseDto { */ pageSize: number; /** - * Array of queue operations + * * @type {Array} * @memberof DeploymentQueueResponseDto */ diff --git a/generated-contracts/models/index.ts b/generated-contracts/models/index.ts index 778fa8b..0089b80 100644 --- a/generated-contracts/models/index.ts +++ b/generated-contracts/models/index.ts @@ -1,43 +1,22 @@ /* tslint:disable */ /* eslint-disable */ -export * from './account-currency-visibility-response-dto'; export * from './account-deployment-dto'; export * from './account-details-dto'; export * from './account-response-dto'; -export * from './address-book-entry-response-dto'; -export * from './address-book-list-response-dto'; -export * from './address-book-list-response-dto-items-inner'; -export * from './api-key-list-response-dto'; -export * from './api-key-list-response-dto-items-inner'; -export * from './api-key-meta-dto'; export * from './asset-balance-dto'; +export * from './asset-balance-short-response-dto'; export * from './asset-balances-response-dto'; -export * from './auth-response-dto'; -export * from './balance-history-response-dto'; -export * from './balance-history-response-dto-items-inner'; export * from './balance-summary-response-dto'; export * from './call-dto'; export * from './callback'; -export * from './callback-secret-response-dto'; export * from './claim-item-dto'; export * from './claims-response-dto'; -export * from './create-account-dto'; -export * from './create-address-book-entry-dto'; -export * from './create-api-key-dto'; -export * from './create-api-key-response-dto'; export * from './create-invoice-dto'; export * from './create-multisig-config-change-operation-dto'; -export * from './create-multisig-config-change-operation-dto-calls-inner'; -export * from './create-payment-body-dto'; export * from './create-payout-dto'; export * from './create-reject-operation-dto'; -export * from './credit-price-item-dto'; -export * from './credits-overview-response-dto'; -export * from './credits-overview-response-dto-unit-prices-inner'; -export * from './credits-overview-response-dto-unit-prices-inner-discounts-inner'; export * from './currencies-controller-find-all-v1-is-native-parameter'; export * from './currency-response-dto'; -export * from './delete-all-operations-response-dto'; export * from './deployment-params-response-dto'; export * from './deployment-queue-response-dto'; export * from './get-callbacks-response-dto'; @@ -47,32 +26,17 @@ export * from './invoices-response-dto'; export * from './network-response-dto'; export * from './networks-response-dto'; export * from './nonce-info-response-dto'; -export * from './nonce-request-dto'; -export * from './nonce-response-dto'; -export * from './operation-catalog-item-dto'; export * from './operation-signature-dto'; -export * from './operation-usages-response-dto'; -export * from './operation-usages-response-dto-items-inner'; -export * from './operation-usages-response-dto-items-inner-api-operation'; export * from './payout-detail-response-dto'; export * from './payout-list-response-dto'; export * from './payout-response-dto'; -export * from './post-rates-body-dto'; -export * from './profile-response-dto'; -export * from './public-invoice-response-dto'; -export * from './public-transaction-list-response-dto'; -export * from './public-transaction-response-dto'; export * from './queue-operation-response-dto'; -export * from './rate-pair-dto'; -export * from './rate-result-dto'; -export * from './rates-response-dto'; -export * from './refresh-token-request-dto'; +export * from './queue-operation-response-dto-dapp-metadata'; +export * from './resend-callbacks-body-dto'; +export * from './resend-callbacks-response-dto'; export * from './signature-response-dto'; export * from './smart-contract-version-response-dto'; export * from './submit-signature-dto'; -export * from './top-ups-response-dto'; -export * from './top-ups-response-dto-items-inner'; -export * from './top-ups-response-dto-items-inner-currency'; export * from './transaction-details-dto'; export * from './transaction-invoice-response-dto'; export * from './transaction-list-response-dto'; @@ -81,10 +45,6 @@ export * from './transactions-controller-get-transactions-v1-currency-is-scam-pa export * from './transactions-controller-get-transactions-v1-currency-is-verified-parameter'; export * from './universal-address'; export * from './update-account-dto'; -export * from './update-address-book-entry-dto'; export * from './update-invoice-dto'; export * from './update-operation-nonce-dto'; export * from './update-payout-dto'; -export * from './update-profile-request-dto'; -export * from './user-response-dto'; -export * from './verify-request-dto'; diff --git a/generated-contracts/models/invoice-response-dto.ts b/generated-contracts/models/invoice-response-dto.ts index 9a8d7b3..b4c0f82 100644 --- a/generated-contracts/models/invoice-response-dto.ts +++ b/generated-contracts/models/invoice-response-dto.ts @@ -28,101 +28,101 @@ import { */ export interface InvoiceResponseDto { /** - * Entity unique identifier + * Requested payment amount * @type {string} * @memberof InvoiceResponseDto */ - id: string; + requestedAmount: string | null; /** - * Invoice public identifier (Snowflake ID) - * @type {string} + * Available currencies for this invoice + * @type {Array} * @memberof InvoiceResponseDto */ - publicId: string; + availableCurrencies: Array; /** - * Invoice payment address + * Custom payment page button URL * @type {string} * @memberof InvoiceResponseDto */ - invoiceAddress: string; + paymentPageButtonUrl: string | null; /** - * Requested payment amount + * Custom payment page button text * @type {string} * @memberof InvoiceResponseDto */ - requestedAmount: string | null; + paymentPageButtonText: string | null; /** - * Paid amount in crypto; null for multi-currency invoices (see paidAmountBaseCurrency) + * Payment page URL for the invoice * @type {string} * @memberof InvoiceResponseDto */ - paidAmount: string | null; + paymentPageUrl: string; /** - * Paid amount converted to user base currency (2 decimals) for multi-currency invoices; null otherwise + * Invoice status * @type {string} * @memberof InvoiceResponseDto */ - paidAmountBaseCurrency: string | null; + status: InvoiceResponseDtoStatusEnum; /** - * Invoice status + * Creation timestamp * @type {string} * @memberof InvoiceResponseDto */ - status: InvoiceResponseDtoStatusEnum; + createdAt: string; /** - * Tracking identifier - * @type {string} + * Whether the entity relates to Tron (TVM) + * @type {boolean} * @memberof InvoiceResponseDto */ - trackingId: string | null; + isTron: boolean; /** - * Callback URL for notifications + * Entity unique identifier * @type {string} * @memberof InvoiceResponseDto */ - callbackUrl: string | null; + id: string; /** - * Custom payment page button URL + * Invoice public identifier (Snowflake ID) * @type {string} * @memberof InvoiceResponseDto */ - paymentPageButtonUrl: string | null; + publicId: string; /** - * Custom payment page button text + * Invoice payment address * @type {string} * @memberof InvoiceResponseDto */ - paymentPageButtonText: string | null; + invoiceAddress: string; /** - * Payment page URL for the invoice + * Paid amount in crypto; null for multi-currency invoices (see paidAmountBaseCurrency) * @type {string} * @memberof InvoiceResponseDto */ - paymentPageUrl: string; + paidAmount: string | null; /** - * Creation timestamp + * Paid amount converted to user base currency (2 decimals) for multi-currency invoices; null otherwise * @type {string} * @memberof InvoiceResponseDto */ - createdAt: string; + paidAmountBaseCurrency: string | null; /** - * Last update timestamp + * Tracking identifier * @type {string} * @memberof InvoiceResponseDto */ - updatedAt: string; + trackingId: string | null; /** - * Available currencies for this invoice - * @type {Array} + * Callback URL for notifications + * @type {string} * @memberof InvoiceResponseDto */ - availableCurrencies: Array; + callbackUrl: string | null; /** - * Whether the entity relates to Tron (TVM) - * @type {boolean} + * Last update timestamp + * @type {string} * @memberof InvoiceResponseDto */ - isTron: boolean; + updatedAt: string; } @@ -141,22 +141,22 @@ export type InvoiceResponseDtoStatusEnum = typeof InvoiceResponseDtoStatusEnum[k * Check if a given object implements the InvoiceResponseDto interface. */ export function instanceOfInvoiceResponseDto(value: object): value is InvoiceResponseDto { + if (!('requestedAmount' in value) || value['requestedAmount'] === undefined) return false; + if (!('availableCurrencies' in value) || value['availableCurrencies'] === undefined) return false; + if (!('paymentPageButtonUrl' in value) || value['paymentPageButtonUrl'] === undefined) return false; + if (!('paymentPageButtonText' in value) || value['paymentPageButtonText'] === undefined) return false; + if (!('paymentPageUrl' in value) || value['paymentPageUrl'] === undefined) return false; + if (!('status' in value) || value['status'] === undefined) return false; + if (!('createdAt' in value) || value['createdAt'] === undefined) return false; + if (!('isTron' in value) || value['isTron'] === undefined) return false; if (!('id' in value) || value['id'] === undefined) return false; if (!('publicId' in value) || value['publicId'] === undefined) return false; if (!('invoiceAddress' in value) || value['invoiceAddress'] === undefined) return false; - if (!('requestedAmount' in value) || value['requestedAmount'] === undefined) return false; if (!('paidAmount' in value) || value['paidAmount'] === undefined) return false; if (!('paidAmountBaseCurrency' in value) || value['paidAmountBaseCurrency'] === undefined) return false; - if (!('status' in value) || value['status'] === undefined) return false; if (!('trackingId' in value) || value['trackingId'] === undefined) return false; if (!('callbackUrl' in value) || value['callbackUrl'] === undefined) return false; - if (!('paymentPageButtonUrl' in value) || value['paymentPageButtonUrl'] === undefined) return false; - if (!('paymentPageButtonText' in value) || value['paymentPageButtonText'] === undefined) return false; - if (!('paymentPageUrl' in value) || value['paymentPageUrl'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; if (!('updatedAt' in value) || value['updatedAt'] === undefined) return false; - if (!('availableCurrencies' in value) || value['availableCurrencies'] === undefined) return false; - if (!('isTron' in value) || value['isTron'] === undefined) return false; return true; } @@ -170,22 +170,22 @@ export function InvoiceResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: } return { + 'requestedAmount': json['requestedAmount'], + 'availableCurrencies': ((json['availableCurrencies'] as Array).map(CurrencyResponseDtoFromJSON)), + 'paymentPageButtonUrl': json['paymentPageButtonUrl'], + 'paymentPageButtonText': json['paymentPageButtonText'], + 'paymentPageUrl': json['paymentPageUrl'], + 'status': json['status'], + 'createdAt': json['createdAt'], + 'isTron': json['isTron'], 'id': json['id'], 'publicId': json['publicId'], 'invoiceAddress': json['invoiceAddress'], - 'requestedAmount': json['requestedAmount'], 'paidAmount': json['paidAmount'], 'paidAmountBaseCurrency': json['paidAmountBaseCurrency'], - 'status': json['status'], 'trackingId': json['trackingId'], 'callbackUrl': json['callbackUrl'], - 'paymentPageButtonUrl': json['paymentPageButtonUrl'], - 'paymentPageButtonText': json['paymentPageButtonText'], - 'paymentPageUrl': json['paymentPageUrl'], - 'createdAt': json['createdAt'], 'updatedAt': json['updatedAt'], - 'availableCurrencies': ((json['availableCurrencies'] as Array).map(CurrencyResponseDtoFromJSON)), - 'isTron': json['isTron'], }; } @@ -200,22 +200,22 @@ export function InvoiceResponseDtoToJSONTyped(value?: InvoiceResponseDto | null, return { + 'requestedAmount': value['requestedAmount'], + 'availableCurrencies': ((value['availableCurrencies'] as Array).map(CurrencyResponseDtoToJSON)), + 'paymentPageButtonUrl': value['paymentPageButtonUrl'], + 'paymentPageButtonText': value['paymentPageButtonText'], + 'paymentPageUrl': value['paymentPageUrl'], + 'status': value['status'], + 'createdAt': value['createdAt'], + 'isTron': value['isTron'], 'id': value['id'], 'publicId': value['publicId'], 'invoiceAddress': value['invoiceAddress'], - 'requestedAmount': value['requestedAmount'], 'paidAmount': value['paidAmount'], 'paidAmountBaseCurrency': value['paidAmountBaseCurrency'], - 'status': value['status'], 'trackingId': value['trackingId'], 'callbackUrl': value['callbackUrl'], - 'paymentPageButtonUrl': value['paymentPageButtonUrl'], - 'paymentPageButtonText': value['paymentPageButtonText'], - 'paymentPageUrl': value['paymentPageUrl'], - 'createdAt': value['createdAt'], 'updatedAt': value['updatedAt'], - 'availableCurrencies': ((value['availableCurrencies'] as Array).map(CurrencyResponseDtoToJSON)), - 'isTron': value['isTron'], }; } diff --git a/generated-contracts/models/invoices-response-dto.ts b/generated-contracts/models/invoices-response-dto.ts index eebbf0e..4fb9858 100644 --- a/generated-contracts/models/invoices-response-dto.ts +++ b/generated-contracts/models/invoices-response-dto.ts @@ -40,13 +40,13 @@ export interface InvoicesResponseDto { */ page: number; /** - * Number of items per page + * Number of items per page (max 100) * @type {number} * @memberof InvoicesResponseDto */ pageSize: number; /** - * List of invoices + * * @type {Array} * @memberof InvoicesResponseDto */ diff --git a/generated-contracts/models/nonce-request-dto.ts b/generated-contracts/models/nonce-request-dto.ts deleted file mode 100644 index 629cc5f..0000000 --- a/generated-contracts/models/nonce-request-dto.ts +++ /dev/null @@ -1,103 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface NonceRequestDto - */ -export interface NonceRequestDto { - /** - * Authentication protocol - * @type {string} - * @memberof NonceRequestDto - */ - protocol?: NonceRequestDtoProtocolEnum; - /** - * Wallet address (Ethereum 0x... or Tron TVM T...) - * @type {string} - * @memberof NonceRequestDto - */ - address: string; - /** - * Chain ID - * @type {string} - * @memberof NonceRequestDto - */ - chainId: string; - /** - * Frontend authentication URL for domain validation (supports both http and https) - * @type {string} - * @memberof NonceRequestDto - */ - authUrl: string; -} - - -/** - * @export - */ -export const NonceRequestDtoProtocolEnum = { - Siwe: 'siwe', - Tron: 'tron' -} as const; -export type NonceRequestDtoProtocolEnum = typeof NonceRequestDtoProtocolEnum[keyof typeof NonceRequestDtoProtocolEnum]; - - -/** - * Check if a given object implements the NonceRequestDto interface. - */ -export function instanceOfNonceRequestDto(value: object): value is NonceRequestDto { - if (!('address' in value) || value['address'] === undefined) return false; - if (!('chainId' in value) || value['chainId'] === undefined) return false; - if (!('authUrl' in value) || value['authUrl'] === undefined) return false; - return true; -} - -export function NonceRequestDtoFromJSON(json: any): NonceRequestDto { - return NonceRequestDtoFromJSONTyped(json, false); -} - -export function NonceRequestDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): NonceRequestDto { - if (json == null) { - return json; - } - return { - - 'protocol': json['protocol'] == null ? undefined : json['protocol'], - 'address': json['address'], - 'chainId': json['chainId'], - 'authUrl': json['authUrl'], - }; -} - -export function NonceRequestDtoToJSON(json: any): NonceRequestDto { - return NonceRequestDtoToJSONTyped(json, false); -} - -export function NonceRequestDtoToJSONTyped(value?: NonceRequestDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'protocol': value['protocol'], - 'address': value['address'], - 'chainId': value['chainId'], - 'authUrl': value['authUrl'], - }; -} - diff --git a/generated-contracts/models/nonce-response-dto.ts b/generated-contracts/models/nonce-response-dto.ts deleted file mode 100644 index 4a4db00..0000000 --- a/generated-contracts/models/nonce-response-dto.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface NonceResponseDto - */ -export interface NonceResponseDto { - /** - * Generated nonce for signing - * @type {string} - * @memberof NonceResponseDto - */ - nonce: string; - /** - * Message to sign - * @type {string} - * @memberof NonceResponseDto - */ - message: string; -} - -/** - * Check if a given object implements the NonceResponseDto interface. - */ -export function instanceOfNonceResponseDto(value: object): value is NonceResponseDto { - if (!('nonce' in value) || value['nonce'] === undefined) return false; - if (!('message' in value) || value['message'] === undefined) return false; - return true; -} - -export function NonceResponseDtoFromJSON(json: any): NonceResponseDto { - return NonceResponseDtoFromJSONTyped(json, false); -} - -export function NonceResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): NonceResponseDto { - if (json == null) { - return json; - } - return { - - 'nonce': json['nonce'], - 'message': json['message'], - }; -} - -export function NonceResponseDtoToJSON(json: any): NonceResponseDto { - return NonceResponseDtoToJSONTyped(json, false); -} - -export function NonceResponseDtoToJSONTyped(value?: NonceResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'nonce': value['nonce'], - 'message': value['message'], - }; -} - diff --git a/generated-contracts/models/operation-catalog-item-dto.ts b/generated-contracts/models/operation-catalog-item-dto.ts deleted file mode 100644 index 641c9b1..0000000 --- a/generated-contracts/models/operation-catalog-item-dto.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface OperationCatalogItemDto - */ -export interface OperationCatalogItemDto { - /** - * Operation code - * @type {string} - * @memberof OperationCatalogItemDto - */ - code: string; - /** - * Operation name - * @type {string} - * @memberof OperationCatalogItemDto - */ - name: string; - /** - * Price in credits (integer) - * @type {number} - * @memberof OperationCatalogItemDto - */ - priceCredits: number; -} - -/** - * Check if a given object implements the OperationCatalogItemDto interface. - */ -export function instanceOfOperationCatalogItemDto(value: object): value is OperationCatalogItemDto { - if (!('code' in value) || value['code'] === undefined) return false; - if (!('name' in value) || value['name'] === undefined) return false; - if (!('priceCredits' in value) || value['priceCredits'] === undefined) return false; - return true; -} - -export function OperationCatalogItemDtoFromJSON(json: any): OperationCatalogItemDto { - return OperationCatalogItemDtoFromJSONTyped(json, false); -} - -export function OperationCatalogItemDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): OperationCatalogItemDto { - if (json == null) { - return json; - } - return { - - 'code': json['code'], - 'name': json['name'], - 'priceCredits': json['priceCredits'], - }; -} - -export function OperationCatalogItemDtoToJSON(json: any): OperationCatalogItemDto { - return OperationCatalogItemDtoToJSONTyped(json, false); -} - -export function OperationCatalogItemDtoToJSONTyped(value?: OperationCatalogItemDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'code': value['code'], - 'name': value['name'], - 'priceCredits': value['priceCredits'], - }; -} - diff --git a/generated-contracts/models/operation-usages-response-dto-items-inner-api-operation.ts b/generated-contracts/models/operation-usages-response-dto-items-inner-api-operation.ts deleted file mode 100644 index d8525a6..0000000 --- a/generated-contracts/models/operation-usages-response-dto-items-inner-api-operation.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface OperationUsagesResponseDtoItemsInnerApiOperation - */ -export interface OperationUsagesResponseDtoItemsInnerApiOperation { - /** - * - * @type {string} - * @memberof OperationUsagesResponseDtoItemsInnerApiOperation - */ - id: string; - /** - * - * @type {string} - * @memberof OperationUsagesResponseDtoItemsInnerApiOperation - */ - code: string; - /** - * - * @type {string} - * @memberof OperationUsagesResponseDtoItemsInnerApiOperation - */ - name: string; -} - -/** - * Check if a given object implements the OperationUsagesResponseDtoItemsInnerApiOperation interface. - */ -export function instanceOfOperationUsagesResponseDtoItemsInnerApiOperation(value: object): value is OperationUsagesResponseDtoItemsInnerApiOperation { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('code' in value) || value['code'] === undefined) return false; - if (!('name' in value) || value['name'] === undefined) return false; - return true; -} - -export function OperationUsagesResponseDtoItemsInnerApiOperationFromJSON(json: any): OperationUsagesResponseDtoItemsInnerApiOperation { - return OperationUsagesResponseDtoItemsInnerApiOperationFromJSONTyped(json, false); -} - -export function OperationUsagesResponseDtoItemsInnerApiOperationFromJSONTyped(json: any, ignoreDiscriminator: boolean): OperationUsagesResponseDtoItemsInnerApiOperation { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'code': json['code'], - 'name': json['name'], - }; -} - -export function OperationUsagesResponseDtoItemsInnerApiOperationToJSON(json: any): OperationUsagesResponseDtoItemsInnerApiOperation { - return OperationUsagesResponseDtoItemsInnerApiOperationToJSONTyped(json, false); -} - -export function OperationUsagesResponseDtoItemsInnerApiOperationToJSONTyped(value?: OperationUsagesResponseDtoItemsInnerApiOperation | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'code': value['code'], - 'name': value['name'], - }; -} - diff --git a/generated-contracts/models/operation-usages-response-dto-items-inner.ts b/generated-contracts/models/operation-usages-response-dto-items-inner.ts deleted file mode 100644 index e0c9c50..0000000 --- a/generated-contracts/models/operation-usages-response-dto-items-inner.ts +++ /dev/null @@ -1,130 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { OperationUsagesResponseDtoItemsInnerApiOperation } from './operation-usages-response-dto-items-inner-api-operation'; -import { - OperationUsagesResponseDtoItemsInnerApiOperationFromJSON, - OperationUsagesResponseDtoItemsInnerApiOperationFromJSONTyped, - OperationUsagesResponseDtoItemsInnerApiOperationToJSON, - OperationUsagesResponseDtoItemsInnerApiOperationToJSONTyped, -} from './operation-usages-response-dto-items-inner-api-operation'; - -/** - * - * @export - * @interface OperationUsagesResponseDtoItemsInner - */ -export interface OperationUsagesResponseDtoItemsInner { - /** - * - * @type {string} - * @memberof OperationUsagesResponseDtoItemsInner - */ - id: string; - /** - * - * @type {string} - * @memberof OperationUsagesResponseDtoItemsInner - */ - accountId: string; - /** - * - * @type {OperationUsagesResponseDtoItemsInnerApiOperation} - * @memberof OperationUsagesResponseDtoItemsInner - */ - apiOperation: OperationUsagesResponseDtoItemsInnerApiOperation; - /** - * - * @type {number} - * @memberof OperationUsagesResponseDtoItemsInner - */ - costCredits: number; - /** - * - * @type {string} - * @memberof OperationUsagesResponseDtoItemsInner - */ - status: OperationUsagesResponseDtoItemsInnerStatusEnum; - /** - * - * @type {Date} - * @memberof OperationUsagesResponseDtoItemsInner - */ - createdAt: Date; -} - - -/** - * @export - */ -export const OperationUsagesResponseDtoItemsInnerStatusEnum = { - Completed: 'completed', - Failed: 'failed' -} as const; -export type OperationUsagesResponseDtoItemsInnerStatusEnum = typeof OperationUsagesResponseDtoItemsInnerStatusEnum[keyof typeof OperationUsagesResponseDtoItemsInnerStatusEnum]; - - -/** - * Check if a given object implements the OperationUsagesResponseDtoItemsInner interface. - */ -export function instanceOfOperationUsagesResponseDtoItemsInner(value: object): value is OperationUsagesResponseDtoItemsInner { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('accountId' in value) || value['accountId'] === undefined) return false; - if (!('apiOperation' in value) || value['apiOperation'] === undefined) return false; - if (!('costCredits' in value) || value['costCredits'] === undefined) return false; - if (!('status' in value) || value['status'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - return true; -} - -export function OperationUsagesResponseDtoItemsInnerFromJSON(json: any): OperationUsagesResponseDtoItemsInner { - return OperationUsagesResponseDtoItemsInnerFromJSONTyped(json, false); -} - -export function OperationUsagesResponseDtoItemsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): OperationUsagesResponseDtoItemsInner { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'accountId': json['accountId'], - 'apiOperation': OperationUsagesResponseDtoItemsInnerApiOperationFromJSON(json['apiOperation']), - 'costCredits': json['costCredits'], - 'status': json['status'], - 'createdAt': (new Date(json['createdAt'])), - }; -} - -export function OperationUsagesResponseDtoItemsInnerToJSON(json: any): OperationUsagesResponseDtoItemsInner { - return OperationUsagesResponseDtoItemsInnerToJSONTyped(json, false); -} - -export function OperationUsagesResponseDtoItemsInnerToJSONTyped(value?: OperationUsagesResponseDtoItemsInner | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'accountId': value['accountId'], - 'apiOperation': OperationUsagesResponseDtoItemsInnerApiOperationToJSON(value['apiOperation']), - 'costCredits': value['costCredits'], - 'status': value['status'], - 'createdAt': value['createdAt'].toISOString(), - }; -} - diff --git a/generated-contracts/models/operation-usages-response-dto.ts b/generated-contracts/models/operation-usages-response-dto.ts deleted file mode 100644 index 6ad98da..0000000 --- a/generated-contracts/models/operation-usages-response-dto.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { OperationUsagesResponseDtoItemsInner } from './operation-usages-response-dto-items-inner'; -import { - OperationUsagesResponseDtoItemsInnerFromJSON, - OperationUsagesResponseDtoItemsInnerFromJSONTyped, - OperationUsagesResponseDtoItemsInnerToJSON, - OperationUsagesResponseDtoItemsInnerToJSONTyped, -} from './operation-usages-response-dto-items-inner'; - -/** - * - * @export - * @interface OperationUsagesResponseDto - */ -export interface OperationUsagesResponseDto { - /** - * - * @type {number} - * @memberof OperationUsagesResponseDto - */ - total: number; - /** - * - * @type {number} - * @memberof OperationUsagesResponseDto - */ - page: number; - /** - * - * @type {number} - * @memberof OperationUsagesResponseDto - */ - pageSize: number; - /** - * - * @type {Array} - * @memberof OperationUsagesResponseDto - */ - items: Array; -} - -/** - * Check if a given object implements the OperationUsagesResponseDto interface. - */ -export function instanceOfOperationUsagesResponseDto(value: object): value is OperationUsagesResponseDto { - if (!('total' in value) || value['total'] === undefined) return false; - if (!('page' in value) || value['page'] === undefined) return false; - if (!('pageSize' in value) || value['pageSize'] === undefined) return false; - if (!('items' in value) || value['items'] === undefined) return false; - return true; -} - -export function OperationUsagesResponseDtoFromJSON(json: any): OperationUsagesResponseDto { - return OperationUsagesResponseDtoFromJSONTyped(json, false); -} - -export function OperationUsagesResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): OperationUsagesResponseDto { - if (json == null) { - return json; - } - return { - - 'total': json['total'], - 'page': json['page'], - 'pageSize': json['pageSize'], - 'items': ((json['items'] as Array).map(OperationUsagesResponseDtoItemsInnerFromJSON)), - }; -} - -export function OperationUsagesResponseDtoToJSON(json: any): OperationUsagesResponseDto { - return OperationUsagesResponseDtoToJSONTyped(json, false); -} - -export function OperationUsagesResponseDtoToJSONTyped(value?: OperationUsagesResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'total': value['total'], - 'page': value['page'], - 'pageSize': value['pageSize'], - 'items': ((value['items'] as Array).map(OperationUsagesResponseDtoItemsInnerToJSON)), - }; -} - diff --git a/generated-contracts/models/payout-detail-response-dto.ts b/generated-contracts/models/payout-detail-response-dto.ts index cfebdb4..c4be3fb 100644 --- a/generated-contracts/models/payout-detail-response-dto.ts +++ b/generated-contracts/models/payout-detail-response-dto.ts @@ -34,7 +34,7 @@ export interface PayoutDetailResponseDto { */ id: string; /** - * The unique ID of the currency, ("{chainId}-{contractAddress}") + * The unique ID of the currency, ("{chainId}" or "{chainId}-{contractAddress}") * @type {string} * @memberof PayoutDetailResponseDto */ diff --git a/generated-contracts/models/payout-response-dto.ts b/generated-contracts/models/payout-response-dto.ts index 165677b..5f91128 100644 --- a/generated-contracts/models/payout-response-dto.ts +++ b/generated-contracts/models/payout-response-dto.ts @@ -34,7 +34,7 @@ export interface PayoutResponseDto { */ id: string; /** - * The unique ID of the currency, ("{chainId}-{contractAddress}") + * The unique ID of the currency, ("{chainId}" or "{chainId}-{contractAddress}") * @type {string} * @memberof PayoutResponseDto */ diff --git a/generated-contracts/models/post-rates-body-dto.ts b/generated-contracts/models/post-rates-body-dto.ts deleted file mode 100644 index e4576a5..0000000 --- a/generated-contracts/models/post-rates-body-dto.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { RatePairDto } from './rate-pair-dto'; -import { - RatePairDtoFromJSON, - RatePairDtoFromJSONTyped, - RatePairDtoToJSON, - RatePairDtoToJSONTyped, -} from './rate-pair-dto'; - -/** - * - * @export - * @interface PostRatesBodyDto - */ -export interface PostRatesBodyDto { - /** - * Array of rate pairs - * @type {Array} - * @memberof PostRatesBodyDto - */ - rates: Array; -} - -/** - * Check if a given object implements the PostRatesBodyDto interface. - */ -export function instanceOfPostRatesBodyDto(value: object): value is PostRatesBodyDto { - if (!('rates' in value) || value['rates'] === undefined) return false; - return true; -} - -export function PostRatesBodyDtoFromJSON(json: any): PostRatesBodyDto { - return PostRatesBodyDtoFromJSONTyped(json, false); -} - -export function PostRatesBodyDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PostRatesBodyDto { - if (json == null) { - return json; - } - return { - - 'rates': ((json['rates'] as Array).map(RatePairDtoFromJSON)), - }; -} - -export function PostRatesBodyDtoToJSON(json: any): PostRatesBodyDto { - return PostRatesBodyDtoToJSONTyped(json, false); -} - -export function PostRatesBodyDtoToJSONTyped(value?: PostRatesBodyDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'rates': ((value['rates'] as Array).map(RatePairDtoToJSON)), - }; -} - diff --git a/generated-contracts/models/profile-response-dto.ts b/generated-contracts/models/profile-response-dto.ts deleted file mode 100644 index c889dc1..0000000 --- a/generated-contracts/models/profile-response-dto.ts +++ /dev/null @@ -1,114 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface ProfileResponseDto - */ -export interface ProfileResponseDto { - /** - * Entity unique identifier - * @type {string} - * @memberof ProfileResponseDto - */ - id: string; - /** - * Base currency for the user profile - * @type {string} - * @memberof ProfileResponseDto - */ - baseCurrency: ProfileResponseDtoBaseCurrencyEnum; - /** - * Whether unverified currencies are hidden for the current user by default - * @type {boolean} - * @memberof ProfileResponseDto - */ - hideUnverifiedCurrencies: boolean; - /** - * Creation timestamp - * @type {string} - * @memberof ProfileResponseDto - */ - createdAt: string; - /** - * Last update timestamp - * @type {string} - * @memberof ProfileResponseDto - */ - updatedAt: string; -} - - -/** - * @export - */ -export const ProfileResponseDtoBaseCurrencyEnum = { - Usd: 'usd', - Eur: 'eur', - Cny: 'cny' -} as const; -export type ProfileResponseDtoBaseCurrencyEnum = typeof ProfileResponseDtoBaseCurrencyEnum[keyof typeof ProfileResponseDtoBaseCurrencyEnum]; - - -/** - * Check if a given object implements the ProfileResponseDto interface. - */ -export function instanceOfProfileResponseDto(value: object): value is ProfileResponseDto { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('baseCurrency' in value) || value['baseCurrency'] === undefined) return false; - if (!('hideUnverifiedCurrencies' in value) || value['hideUnverifiedCurrencies'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('updatedAt' in value) || value['updatedAt'] === undefined) return false; - return true; -} - -export function ProfileResponseDtoFromJSON(json: any): ProfileResponseDto { - return ProfileResponseDtoFromJSONTyped(json, false); -} - -export function ProfileResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ProfileResponseDto { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'baseCurrency': json['baseCurrency'], - 'hideUnverifiedCurrencies': json['hideUnverifiedCurrencies'], - 'createdAt': json['createdAt'], - 'updatedAt': json['updatedAt'], - }; -} - -export function ProfileResponseDtoToJSON(json: any): ProfileResponseDto { - return ProfileResponseDtoToJSONTyped(json, false); -} - -export function ProfileResponseDtoToJSONTyped(value?: ProfileResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'baseCurrency': value['baseCurrency'], - 'hideUnverifiedCurrencies': value['hideUnverifiedCurrencies'], - 'createdAt': value['createdAt'], - 'updatedAt': value['updatedAt'], - }; -} - diff --git a/generated-contracts/models/public-invoice-response-dto.ts b/generated-contracts/models/public-invoice-response-dto.ts deleted file mode 100644 index a8b95b7..0000000 --- a/generated-contracts/models/public-invoice-response-dto.ts +++ /dev/null @@ -1,176 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { CurrencyResponseDto } from './currency-response-dto'; -import { - CurrencyResponseDtoFromJSON, - CurrencyResponseDtoFromJSONTyped, - CurrencyResponseDtoToJSON, - CurrencyResponseDtoToJSONTyped, -} from './currency-response-dto'; - -/** - * - * @export - * @interface PublicInvoiceResponseDto - */ -export interface PublicInvoiceResponseDto { - /** - * Invoice public identifier (Snowflake ID) - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - publicId: string; - /** - * Invoice payment address - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - invoiceAddress: string; - /** - * Chain ID - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - chainId: string; - /** - * Requested payment amount - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - requestedAmount: string | null; - /** - * Available currencies for this invoice - * @type {Array} - * @memberof PublicInvoiceResponseDto - */ - availableCurrencies: Array; - /** - * Custom payment page button URL - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - paymentPageButtonUrl: string | null; - /** - * Custom payment page button text - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - paymentPageButtonText: string | null; - /** - * Payment page URL for the invoice - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - paymentPageUrl: string; - /** - * Invoice status - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - status: PublicInvoiceResponseDtoStatusEnum; - /** - * Creation timestamp - * @type {string} - * @memberof PublicInvoiceResponseDto - */ - createdAt: string; - /** - * Whether the entity relates to Tron (TVM) - * @type {boolean} - * @memberof PublicInvoiceResponseDto - */ - isTron: boolean; -} - - -/** - * @export - */ -export const PublicInvoiceResponseDtoStatusEnum = { - Created: 'CREATED', - Paid: 'PAID', - Unresolved: 'UNRESOLVED' -} as const; -export type PublicInvoiceResponseDtoStatusEnum = typeof PublicInvoiceResponseDtoStatusEnum[keyof typeof PublicInvoiceResponseDtoStatusEnum]; - - -/** - * Check if a given object implements the PublicInvoiceResponseDto interface. - */ -export function instanceOfPublicInvoiceResponseDto(value: object): value is PublicInvoiceResponseDto { - if (!('publicId' in value) || value['publicId'] === undefined) return false; - if (!('invoiceAddress' in value) || value['invoiceAddress'] === undefined) return false; - if (!('chainId' in value) || value['chainId'] === undefined) return false; - if (!('requestedAmount' in value) || value['requestedAmount'] === undefined) return false; - if (!('availableCurrencies' in value) || value['availableCurrencies'] === undefined) return false; - if (!('paymentPageButtonUrl' in value) || value['paymentPageButtonUrl'] === undefined) return false; - if (!('paymentPageButtonText' in value) || value['paymentPageButtonText'] === undefined) return false; - if (!('paymentPageUrl' in value) || value['paymentPageUrl'] === undefined) return false; - if (!('status' in value) || value['status'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('isTron' in value) || value['isTron'] === undefined) return false; - return true; -} - -export function PublicInvoiceResponseDtoFromJSON(json: any): PublicInvoiceResponseDto { - return PublicInvoiceResponseDtoFromJSONTyped(json, false); -} - -export function PublicInvoiceResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PublicInvoiceResponseDto { - if (json == null) { - return json; - } - return { - - 'publicId': json['publicId'], - 'invoiceAddress': json['invoiceAddress'], - 'chainId': json['chainId'], - 'requestedAmount': json['requestedAmount'], - 'availableCurrencies': ((json['availableCurrencies'] as Array).map(CurrencyResponseDtoFromJSON)), - 'paymentPageButtonUrl': json['paymentPageButtonUrl'], - 'paymentPageButtonText': json['paymentPageButtonText'], - 'paymentPageUrl': json['paymentPageUrl'], - 'status': json['status'], - 'createdAt': json['createdAt'], - 'isTron': json['isTron'], - }; -} - -export function PublicInvoiceResponseDtoToJSON(json: any): PublicInvoiceResponseDto { - return PublicInvoiceResponseDtoToJSONTyped(json, false); -} - -export function PublicInvoiceResponseDtoToJSONTyped(value?: PublicInvoiceResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'publicId': value['publicId'], - 'invoiceAddress': value['invoiceAddress'], - 'chainId': value['chainId'], - 'requestedAmount': value['requestedAmount'], - 'availableCurrencies': ((value['availableCurrencies'] as Array).map(CurrencyResponseDtoToJSON)), - 'paymentPageButtonUrl': value['paymentPageButtonUrl'], - 'paymentPageButtonText': value['paymentPageButtonText'], - 'paymentPageUrl': value['paymentPageUrl'], - 'status': value['status'], - 'createdAt': value['createdAt'], - 'isTron': value['isTron'], - }; -} - diff --git a/generated-contracts/models/public-transaction-list-response-dto.ts b/generated-contracts/models/public-transaction-list-response-dto.ts deleted file mode 100644 index 17a57c3..0000000 --- a/generated-contracts/models/public-transaction-list-response-dto.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { PublicTransactionResponseDto } from './public-transaction-response-dto'; -import { - PublicTransactionResponseDtoFromJSON, - PublicTransactionResponseDtoFromJSONTyped, - PublicTransactionResponseDtoToJSON, - PublicTransactionResponseDtoToJSONTyped, -} from './public-transaction-response-dto'; - -/** - * - * @export - * @interface PublicTransactionListResponseDto - */ -export interface PublicTransactionListResponseDto { - /** - * List of transactions - * @type {Array} - * @memberof PublicTransactionListResponseDto - */ - items: Array; - /** - * Total number of items - * @type {number} - * @memberof PublicTransactionListResponseDto - */ - total: number; - /** - * Current page number - * @type {number} - * @memberof PublicTransactionListResponseDto - */ - page: number; - /** - * Number of items per page - * @type {number} - * @memberof PublicTransactionListResponseDto - */ - pageSize: number; -} - -/** - * Check if a given object implements the PublicTransactionListResponseDto interface. - */ -export function instanceOfPublicTransactionListResponseDto(value: object): value is PublicTransactionListResponseDto { - if (!('items' in value) || value['items'] === undefined) return false; - if (!('total' in value) || value['total'] === undefined) return false; - if (!('page' in value) || value['page'] === undefined) return false; - if (!('pageSize' in value) || value['pageSize'] === undefined) return false; - return true; -} - -export function PublicTransactionListResponseDtoFromJSON(json: any): PublicTransactionListResponseDto { - return PublicTransactionListResponseDtoFromJSONTyped(json, false); -} - -export function PublicTransactionListResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PublicTransactionListResponseDto { - if (json == null) { - return json; - } - return { - - 'items': ((json['items'] as Array).map(PublicTransactionResponseDtoFromJSON)), - 'total': json['total'], - 'page': json['page'], - 'pageSize': json['pageSize'], - }; -} - -export function PublicTransactionListResponseDtoToJSON(json: any): PublicTransactionListResponseDto { - return PublicTransactionListResponseDtoToJSONTyped(json, false); -} - -export function PublicTransactionListResponseDtoToJSONTyped(value?: PublicTransactionListResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'items': ((value['items'] as Array).map(PublicTransactionResponseDtoToJSON)), - 'total': value['total'], - 'page': value['page'], - 'pageSize': value['pageSize'], - }; -} - diff --git a/generated-contracts/models/public-transaction-response-dto.ts b/generated-contracts/models/public-transaction-response-dto.ts deleted file mode 100644 index 937c674..0000000 --- a/generated-contracts/models/public-transaction-response-dto.ts +++ /dev/null @@ -1,196 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { CurrencyResponseDto } from './currency-response-dto'; -import { - CurrencyResponseDtoFromJSON, - CurrencyResponseDtoFromJSONTyped, - CurrencyResponseDtoToJSON, - CurrencyResponseDtoToJSONTyped, -} from './currency-response-dto'; - -/** - * - * @export - * @interface PublicTransactionResponseDto - */ -export interface PublicTransactionResponseDto { - /** - * Entity unique identifier - * @type {string} - * @memberof PublicTransactionResponseDto - */ - id: string; - /** - * Transaction direction (IN for deposits, OUT for claims/payouts) - * @type {string} - * @memberof PublicTransactionResponseDto - * @deprecated - */ - direction: PublicTransactionResponseDtoDirectionEnum; - /** - * Transaction status - * @type {string} - * @memberof PublicTransactionResponseDto - */ - status: PublicTransactionResponseDtoStatusEnum; - /** - * Chain ID - * @type {string} - * @memberof PublicTransactionResponseDto - */ - chainId: string; - /** - * Blockchain transaction hash - * @type {string} - * @memberof PublicTransactionResponseDto - */ - txHash: string; - /** - * The unique ID of the currency, ("{chainId}-{contractAddress}") - * @type {string} - * @memberof PublicTransactionResponseDto - */ - currencyId: string; - /** - * Amount value - * @type {string} - * @memberof PublicTransactionResponseDto - */ - amount: string; - /** - * Receiver address - * @type {string} - * @memberof PublicTransactionResponseDto - */ - toAddress: string; - /** - * Block number of deployment - * @type {number} - * @memberof PublicTransactionResponseDto - */ - blockNumber: number | null; - /** - * Number of blockchain confirmations - * @type {number} - * @memberof PublicTransactionResponseDto - */ - confirmations: number; - /** - * Creation timestamp - * @type {string} - * @memberof PublicTransactionResponseDto - */ - createdAt: string; - /** - * Currency details - * @type {CurrencyResponseDto} - * @memberof PublicTransactionResponseDto - */ - currency: CurrencyResponseDto; -} - - -/** - * @export - */ -export const PublicTransactionResponseDtoDirectionEnum = { - In: 'IN', - Out: 'OUT' -} as const; -export type PublicTransactionResponseDtoDirectionEnum = typeof PublicTransactionResponseDtoDirectionEnum[keyof typeof PublicTransactionResponseDtoDirectionEnum]; - -/** - * @export - */ -export const PublicTransactionResponseDtoStatusEnum = { - Pending: 'PENDING', - Executed: 'EXECUTED', - Confirmed: 'CONFIRMED', - Failed: 'FAILED' -} as const; -export type PublicTransactionResponseDtoStatusEnum = typeof PublicTransactionResponseDtoStatusEnum[keyof typeof PublicTransactionResponseDtoStatusEnum]; - - -/** - * Check if a given object implements the PublicTransactionResponseDto interface. - */ -export function instanceOfPublicTransactionResponseDto(value: object): value is PublicTransactionResponseDto { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('direction' in value) || value['direction'] === undefined) return false; - if (!('status' in value) || value['status'] === undefined) return false; - if (!('chainId' in value) || value['chainId'] === undefined) return false; - if (!('txHash' in value) || value['txHash'] === undefined) return false; - if (!('currencyId' in value) || value['currencyId'] === undefined) return false; - if (!('amount' in value) || value['amount'] === undefined) return false; - if (!('toAddress' in value) || value['toAddress'] === undefined) return false; - if (!('blockNumber' in value) || value['blockNumber'] === undefined) return false; - if (!('confirmations' in value) || value['confirmations'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('currency' in value) || value['currency'] === undefined) return false; - return true; -} - -export function PublicTransactionResponseDtoFromJSON(json: any): PublicTransactionResponseDto { - return PublicTransactionResponseDtoFromJSONTyped(json, false); -} - -export function PublicTransactionResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PublicTransactionResponseDto { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'direction': json['direction'], - 'status': json['status'], - 'chainId': json['chainId'], - 'txHash': json['txHash'], - 'currencyId': json['currencyId'], - 'amount': json['amount'], - 'toAddress': json['toAddress'], - 'blockNumber': json['blockNumber'], - 'confirmations': json['confirmations'], - 'createdAt': json['createdAt'], - 'currency': CurrencyResponseDtoFromJSON(json['currency']), - }; -} - -export function PublicTransactionResponseDtoToJSON(json: any): PublicTransactionResponseDto { - return PublicTransactionResponseDtoToJSONTyped(json, false); -} - -export function PublicTransactionResponseDtoToJSONTyped(value?: PublicTransactionResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'direction': value['direction'], - 'status': value['status'], - 'chainId': value['chainId'], - 'txHash': value['txHash'], - 'currencyId': value['currencyId'], - 'amount': value['amount'], - 'toAddress': value['toAddress'], - 'blockNumber': value['blockNumber'], - 'confirmations': value['confirmations'], - 'createdAt': value['createdAt'], - 'currency': CurrencyResponseDtoToJSON(value['currency']), - }; -} - diff --git a/generated-contracts/models/queue-operation-response-dto-dapp-metadata.ts b/generated-contracts/models/queue-operation-response-dto-dapp-metadata.ts new file mode 100644 index 0000000..3a37411 --- /dev/null +++ b/generated-contracts/models/queue-operation-response-dto-dapp-metadata.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * DeFi API (API users) + * API surface available via API key authentication + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface QueueOperationResponseDtoDappMetadata + */ +export interface QueueOperationResponseDtoDappMetadata { + /** + * Name of the connected dApp + * @type {string} + * @memberof QueueOperationResponseDtoDappMetadata + */ + dappName?: string; + /** + * URL of the connected dApp + * @type {string} + * @memberof QueueOperationResponseDtoDappMetadata + */ + dappUrl?: string; + /** + * Icon URL of the connected dApp + * @type {string} + * @memberof QueueOperationResponseDtoDappMetadata + */ + icon?: string; +} + +/** + * Check if a given object implements the QueueOperationResponseDtoDappMetadata interface. + */ +export function instanceOfQueueOperationResponseDtoDappMetadata(value: object): value is QueueOperationResponseDtoDappMetadata { + return true; +} + +export function QueueOperationResponseDtoDappMetadataFromJSON(json: any): QueueOperationResponseDtoDappMetadata { + return QueueOperationResponseDtoDappMetadataFromJSONTyped(json, false); +} + +export function QueueOperationResponseDtoDappMetadataFromJSONTyped(json: any, ignoreDiscriminator: boolean): QueueOperationResponseDtoDappMetadata { + if (json == null) { + return json; + } + return { + + 'dappName': json['dappName'] == null ? undefined : json['dappName'], + 'dappUrl': json['dappUrl'] == null ? undefined : json['dappUrl'], + 'icon': json['icon'] == null ? undefined : json['icon'], + }; +} + +export function QueueOperationResponseDtoDappMetadataToJSON(json: any): QueueOperationResponseDtoDappMetadata { + return QueueOperationResponseDtoDappMetadataToJSONTyped(json, false); +} + +export function QueueOperationResponseDtoDappMetadataToJSONTyped(value?: QueueOperationResponseDtoDappMetadata | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'dappName': value['dappName'], + 'dappUrl': value['dappUrl'], + 'icon': value['icon'], + }; +} + diff --git a/generated-contracts/models/queue-operation-response-dto.ts b/generated-contracts/models/queue-operation-response-dto.ts index 5f7b683..a84554a 100644 --- a/generated-contracts/models/queue-operation-response-dto.ts +++ b/generated-contracts/models/queue-operation-response-dto.ts @@ -27,6 +27,13 @@ import { CallDtoToJSON, CallDtoToJSONTyped, } from './call-dto'; +import type { QueueOperationResponseDtoDappMetadata } from './queue-operation-response-dto-dapp-metadata'; +import { + QueueOperationResponseDtoDappMetadataFromJSON, + QueueOperationResponseDtoDappMetadataFromJSONTyped, + QueueOperationResponseDtoDappMetadataToJSON, + QueueOperationResponseDtoDappMetadataToJSONTyped, +} from './queue-operation-response-dto-dapp-metadata'; /** * @@ -82,18 +89,18 @@ export interface QueueOperationResponseDto { * @memberof QueueOperationResponseDto */ signaturesCollected: number; - /** - * Blockchain transaction hash - * @type {string} - * @memberof QueueOperationResponseDto - */ - txHash: string | null; /** * Number of signatures required * @type {number} * @memberof QueueOperationResponseDto */ signaturesRequired: number; + /** + * Blockchain transaction hash + * @type {string} + * @memberof QueueOperationResponseDto + */ + txHash: string | null; /** * Whether current user has signed * @type {boolean} @@ -148,6 +155,18 @@ export interface QueueOperationResponseDto { * @memberof QueueOperationResponseDto */ signatures: Array; + /** + * Operation expiry timestamp (for DAPP_TRANSACTION operations) + * @type {string} + * @memberof QueueOperationResponseDto + */ + expiresAt?: string | null; + /** + * + * @type {QueueOperationResponseDtoDappMetadata} + * @memberof QueueOperationResponseDto + */ + dappMetadata?: QueueOperationResponseDtoDappMetadata | null; } @@ -157,7 +176,8 @@ export interface QueueOperationResponseDto { export const QueueOperationResponseDtoOperationTypeEnum = { MultisigConfigChange: 'MULTISIG_CONFIG_CHANGE', Reject: 'REJECT', - Payout: 'PAYOUT' + Payout: 'PAYOUT', + DappTransaction: 'DAPP_TRANSACTION' } as const; export type QueueOperationResponseDtoOperationTypeEnum = typeof QueueOperationResponseDtoOperationTypeEnum[keyof typeof QueueOperationResponseDtoOperationTypeEnum]; @@ -167,7 +187,6 @@ export type QueueOperationResponseDtoOperationTypeEnum = typeof QueueOperationRe export const QueueOperationResponseDtoStatusEnum = { Pending: 'PENDING', Ready: 'READY', - Executing: 'EXECUTING', Executed: 'EXECUTED', Failed: 'FAILED', Cancelled: 'CANCELLED' @@ -187,8 +206,8 @@ export function instanceOfQueueOperationResponseDto(value: object): value is Que if (!('calls' in value) || value['calls'] === undefined) return false; if (!('payload' in value) || value['payload'] === undefined) return false; if (!('signaturesCollected' in value) || value['signaturesCollected'] === undefined) return false; - if (!('txHash' in value) || value['txHash'] === undefined) return false; if (!('signaturesRequired' in value) || value['signaturesRequired'] === undefined) return false; + if (!('txHash' in value) || value['txHash'] === undefined) return false; if (!('userSigned' in value) || value['userSigned'] === undefined) return false; if (!('canSign' in value) || value['canSign'] === undefined) return false; if (!('canExecute' in value) || value['canExecute'] === undefined) return false; @@ -219,8 +238,8 @@ export function QueueOperationResponseDtoFromJSONTyped(json: any, ignoreDiscrimi 'calls': ((json['calls'] as Array).map(CallDtoFromJSON)), 'payload': json['payload'], 'signaturesCollected': json['signaturesCollected'], - 'txHash': json['txHash'], 'signaturesRequired': json['signaturesRequired'], + 'txHash': json['txHash'], 'userSigned': json['userSigned'], 'canSign': json['canSign'], 'canExecute': json['canExecute'], @@ -230,6 +249,8 @@ export function QueueOperationResponseDtoFromJSONTyped(json: any, ignoreDiscrimi 'createdAt': json['createdAt'], 'createdBy': json['createdBy'], 'signatures': ((json['signatures'] as Array).map(OperationSignatureDtoFromJSON)), + 'expiresAt': json['expiresAt'] == null ? undefined : json['expiresAt'], + 'dappMetadata': json['dappMetadata'] == null ? undefined : QueueOperationResponseDtoDappMetadataFromJSON(json['dappMetadata']), }; } @@ -252,8 +273,8 @@ export function QueueOperationResponseDtoToJSONTyped(value?: QueueOperationRespo 'calls': ((value['calls'] as Array).map(CallDtoToJSON)), 'payload': value['payload'], 'signaturesCollected': value['signaturesCollected'], - 'txHash': value['txHash'], 'signaturesRequired': value['signaturesRequired'], + 'txHash': value['txHash'], 'userSigned': value['userSigned'], 'canSign': value['canSign'], 'canExecute': value['canExecute'], @@ -263,6 +284,8 @@ export function QueueOperationResponseDtoToJSONTyped(value?: QueueOperationRespo 'createdAt': value['createdAt'], 'createdBy': value['createdBy'], 'signatures': ((value['signatures'] as Array).map(OperationSignatureDtoToJSON)), + 'expiresAt': value['expiresAt'], + 'dappMetadata': QueueOperationResponseDtoDappMetadataToJSON(value['dappMetadata']), }; } diff --git a/generated-contracts/models/rate-pair-dto.ts b/generated-contracts/models/rate-pair-dto.ts deleted file mode 100644 index 5847bee..0000000 --- a/generated-contracts/models/rate-pair-dto.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface RatePairDto - */ -export interface RatePairDto { - /** - * Currency ID from DB - * @type {string} - * @memberof RatePairDto - */ - from: string; - /** - * Target fiat currency - * @type {string} - * @memberof RatePairDto - */ - to: RatePairDtoToEnum; -} - - -/** - * @export - */ -export const RatePairDtoToEnum = { - Usd: 'usd', - Eur: 'eur', - Cny: 'cny' -} as const; -export type RatePairDtoToEnum = typeof RatePairDtoToEnum[keyof typeof RatePairDtoToEnum]; - - -/** - * Check if a given object implements the RatePairDto interface. - */ -export function instanceOfRatePairDto(value: object): value is RatePairDto { - if (!('from' in value) || value['from'] === undefined) return false; - if (!('to' in value) || value['to'] === undefined) return false; - return true; -} - -export function RatePairDtoFromJSON(json: any): RatePairDto { - return RatePairDtoFromJSONTyped(json, false); -} - -export function RatePairDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): RatePairDto { - if (json == null) { - return json; - } - return { - - 'from': json['from'], - 'to': json['to'], - }; -} - -export function RatePairDtoToJSON(json: any): RatePairDto { - return RatePairDtoToJSONTyped(json, false); -} - -export function RatePairDtoToJSONTyped(value?: RatePairDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'from': value['from'], - 'to': value['to'], - }; -} - diff --git a/generated-contracts/models/rate-result-dto.ts b/generated-contracts/models/rate-result-dto.ts deleted file mode 100644 index ece0965..0000000 --- a/generated-contracts/models/rate-result-dto.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface RateResultDto - */ -export interface RateResultDto { - /** - * Currency ID from DB - * @type {string} - * @memberof RateResultDto - */ - from: string; - /** - * Target fiat currency - * @type {string} - * @memberof RateResultDto - */ - to: RateResultDtoToEnum; - /** - * Exchange rate (1 from in to) - * @type {number} - * @memberof RateResultDto - */ - exchangeRate: number; -} - - -/** - * @export - */ -export const RateResultDtoToEnum = { - Usd: 'usd', - Eur: 'eur', - Cny: 'cny' -} as const; -export type RateResultDtoToEnum = typeof RateResultDtoToEnum[keyof typeof RateResultDtoToEnum]; - - -/** - * Check if a given object implements the RateResultDto interface. - */ -export function instanceOfRateResultDto(value: object): value is RateResultDto { - if (!('from' in value) || value['from'] === undefined) return false; - if (!('to' in value) || value['to'] === undefined) return false; - if (!('exchangeRate' in value) || value['exchangeRate'] === undefined) return false; - return true; -} - -export function RateResultDtoFromJSON(json: any): RateResultDto { - return RateResultDtoFromJSONTyped(json, false); -} - -export function RateResultDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): RateResultDto { - if (json == null) { - return json; - } - return { - - 'from': json['from'], - 'to': json['to'], - 'exchangeRate': json['exchangeRate'], - }; -} - -export function RateResultDtoToJSON(json: any): RateResultDto { - return RateResultDtoToJSONTyped(json, false); -} - -export function RateResultDtoToJSONTyped(value?: RateResultDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'from': value['from'], - 'to': value['to'], - 'exchangeRate': value['exchangeRate'], - }; -} - diff --git a/generated-contracts/models/rates-response-dto.ts b/generated-contracts/models/rates-response-dto.ts deleted file mode 100644 index ce85985..0000000 --- a/generated-contracts/models/rates-response-dto.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { RateResultDto } from './rate-result-dto'; -import { - RateResultDtoFromJSON, - RateResultDtoFromJSONTyped, - RateResultDtoToJSON, - RateResultDtoToJSONTyped, -} from './rate-result-dto'; - -/** - * - * @export - * @interface RatesResponseDto - */ -export interface RatesResponseDto { - /** - * - * @type {Array} - * @memberof RatesResponseDto - */ - results: Array; -} - -/** - * Check if a given object implements the RatesResponseDto interface. - */ -export function instanceOfRatesResponseDto(value: object): value is RatesResponseDto { - if (!('results' in value) || value['results'] === undefined) return false; - return true; -} - -export function RatesResponseDtoFromJSON(json: any): RatesResponseDto { - return RatesResponseDtoFromJSONTyped(json, false); -} - -export function RatesResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): RatesResponseDto { - if (json == null) { - return json; - } - return { - - 'results': ((json['results'] as Array).map(RateResultDtoFromJSON)), - }; -} - -export function RatesResponseDtoToJSON(json: any): RatesResponseDto { - return RatesResponseDtoToJSONTyped(json, false); -} - -export function RatesResponseDtoToJSONTyped(value?: RatesResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'results': ((value['results'] as Array).map(RateResultDtoToJSON)), - }; -} - diff --git a/generated-contracts/models/refresh-token-request-dto.ts b/generated-contracts/models/refresh-token-request-dto.ts deleted file mode 100644 index 7df6c3f..0000000 --- a/generated-contracts/models/refresh-token-request-dto.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface RefreshTokenRequestDto - */ -export interface RefreshTokenRequestDto { - /** - * - * @type {string} - * @memberof RefreshTokenRequestDto - */ - refreshToken: string; -} - -/** - * Check if a given object implements the RefreshTokenRequestDto interface. - */ -export function instanceOfRefreshTokenRequestDto(value: object): value is RefreshTokenRequestDto { - if (!('refreshToken' in value) || value['refreshToken'] === undefined) return false; - return true; -} - -export function RefreshTokenRequestDtoFromJSON(json: any): RefreshTokenRequestDto { - return RefreshTokenRequestDtoFromJSONTyped(json, false); -} - -export function RefreshTokenRequestDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): RefreshTokenRequestDto { - if (json == null) { - return json; - } - return { - - 'refreshToken': json['refreshToken'], - }; -} - -export function RefreshTokenRequestDtoToJSON(json: any): RefreshTokenRequestDto { - return RefreshTokenRequestDtoToJSONTyped(json, false); -} - -export function RefreshTokenRequestDtoToJSONTyped(value?: RefreshTokenRequestDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'refreshToken': value['refreshToken'], - }; -} - diff --git a/generated-contracts/models/resend-callbacks-body-dto.ts b/generated-contracts/models/resend-callbacks-body-dto.ts new file mode 100644 index 0000000..3f47233 --- /dev/null +++ b/generated-contracts/models/resend-callbacks-body-dto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * DeFi API (API users) + * API surface available via API key authentication + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ResendCallbacksBodyDto + */ +export interface ResendCallbacksBodyDto { + /** + * Array of callback IDs to resend + * @type {Array} + * @memberof ResendCallbacksBodyDto + */ + ids: Array; +} + +/** + * Check if a given object implements the ResendCallbacksBodyDto interface. + */ +export function instanceOfResendCallbacksBodyDto(value: object): value is ResendCallbacksBodyDto { + if (!('ids' in value) || value['ids'] === undefined) return false; + return true; +} + +export function ResendCallbacksBodyDtoFromJSON(json: any): ResendCallbacksBodyDto { + return ResendCallbacksBodyDtoFromJSONTyped(json, false); +} + +export function ResendCallbacksBodyDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ResendCallbacksBodyDto { + if (json == null) { + return json; + } + return { + + 'ids': json['ids'], + }; +} + +export function ResendCallbacksBodyDtoToJSON(json: any): ResendCallbacksBodyDto { + return ResendCallbacksBodyDtoToJSONTyped(json, false); +} + +export function ResendCallbacksBodyDtoToJSONTyped(value?: ResendCallbacksBodyDto | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'ids': value['ids'], + }; +} + diff --git a/generated-contracts/models/resend-callbacks-response-dto.ts b/generated-contracts/models/resend-callbacks-response-dto.ts new file mode 100644 index 0000000..47f982b --- /dev/null +++ b/generated-contracts/models/resend-callbacks-response-dto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * DeFi API (API users) + * API surface available via API key authentication + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ResendCallbacksResponseDto + */ +export interface ResendCallbacksResponseDto { + /** + * Number of callbacks re-queued for delivery + * @type {number} + * @memberof ResendCallbacksResponseDto + */ + requeuedCount: number; +} + +/** + * Check if a given object implements the ResendCallbacksResponseDto interface. + */ +export function instanceOfResendCallbacksResponseDto(value: object): value is ResendCallbacksResponseDto { + if (!('requeuedCount' in value) || value['requeuedCount'] === undefined) return false; + return true; +} + +export function ResendCallbacksResponseDtoFromJSON(json: any): ResendCallbacksResponseDto { + return ResendCallbacksResponseDtoFromJSONTyped(json, false); +} + +export function ResendCallbacksResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ResendCallbacksResponseDto { + if (json == null) { + return json; + } + return { + + 'requeuedCount': json['requeuedCount'], + }; +} + +export function ResendCallbacksResponseDtoToJSON(json: any): ResendCallbacksResponseDto { + return ResendCallbacksResponseDtoToJSONTyped(json, false); +} + +export function ResendCallbacksResponseDtoToJSONTyped(value?: ResendCallbacksResponseDto | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'requeuedCount': value['requeuedCount'], + }; +} + diff --git a/generated-contracts/models/signature-response-dto.ts b/generated-contracts/models/signature-response-dto.ts index 92d2dec..cf68afe 100644 --- a/generated-contracts/models/signature-response-dto.ts +++ b/generated-contracts/models/signature-response-dto.ts @@ -27,12 +27,6 @@ import { * @interface SignatureResponseDto */ export interface SignatureResponseDto { - /** - * Queue operation unique identifier - * @type {string} - * @memberof SignatureResponseDto - */ - operationId: string; /** * Number of signatures collected * @type {number} @@ -63,18 +57,24 @@ export interface SignatureResponseDto { * @memberof SignatureResponseDto */ signatures: Array; + /** + * Queue operation unique identifier + * @type {string} + * @memberof SignatureResponseDto + */ + operationId: string; } /** * Check if a given object implements the SignatureResponseDto interface. */ export function instanceOfSignatureResponseDto(value: object): value is SignatureResponseDto { - if (!('operationId' in value) || value['operationId'] === undefined) return false; if (!('signaturesCollected' in value) || value['signaturesCollected'] === undefined) return false; if (!('signaturesRequired' in value) || value['signaturesRequired'] === undefined) return false; if (!('canExecute' in value) || value['canExecute'] === undefined) return false; if (!('userSigned' in value) || value['userSigned'] === undefined) return false; if (!('signatures' in value) || value['signatures'] === undefined) return false; + if (!('operationId' in value) || value['operationId'] === undefined) return false; return true; } @@ -88,12 +88,12 @@ export function SignatureResponseDtoFromJSONTyped(json: any, ignoreDiscriminator } return { - 'operationId': json['operationId'], 'signaturesCollected': json['signaturesCollected'], 'signaturesRequired': json['signaturesRequired'], 'canExecute': json['canExecute'], 'userSigned': json['userSigned'], 'signatures': ((json['signatures'] as Array).map(OperationSignatureDtoFromJSON)), + 'operationId': json['operationId'], }; } @@ -108,12 +108,12 @@ export function SignatureResponseDtoToJSONTyped(value?: SignatureResponseDto | n return { - 'operationId': value['operationId'], 'signaturesCollected': value['signaturesCollected'], 'signaturesRequired': value['signaturesRequired'], 'canExecute': value['canExecute'], 'userSigned': value['userSigned'], 'signatures': ((value['signatures'] as Array).map(OperationSignatureDtoToJSON)), + 'operationId': value['operationId'], }; } diff --git a/generated-contracts/models/top-ups-response-dto-items-inner-currency.ts b/generated-contracts/models/top-ups-response-dto-items-inner-currency.ts deleted file mode 100644 index ccd65b9..0000000 --- a/generated-contracts/models/top-ups-response-dto-items-inner-currency.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { UniversalAddress } from './universal-address'; -import { - UniversalAddressFromJSON, - UniversalAddressFromJSONTyped, - UniversalAddressToJSON, - UniversalAddressToJSONTyped, -} from './universal-address'; - -/** - * - * @export - * @interface TopUpsResponseDtoItemsInnerCurrency - */ -export interface TopUpsResponseDtoItemsInnerCurrency { - /** - * - * @type {string} - * @memberof TopUpsResponseDtoItemsInnerCurrency - */ - id: string; - /** - * - * @type {string} - * @memberof TopUpsResponseDtoItemsInnerCurrency - */ - symbol: string; - /** - * - * @type {string} - * @memberof TopUpsResponseDtoItemsInnerCurrency - */ - name: string; - /** - * Chain ID - * @type {string} - * @memberof TopUpsResponseDtoItemsInnerCurrency - */ - chainId: string; - /** - * - * @type {UniversalAddress} - * @memberof TopUpsResponseDtoItemsInnerCurrency - */ - address: UniversalAddress | null; - /** - * - * @type {number} - * @memberof TopUpsResponseDtoItemsInnerCurrency - */ - decimals: number; - /** - * - * @type {boolean} - * @memberof TopUpsResponseDtoItemsInnerCurrency - */ - isScam: boolean; - /** - * - * @type {boolean} - * @memberof TopUpsResponseDtoItemsInnerCurrency - */ - isVerified: boolean; -} - -/** - * Check if a given object implements the TopUpsResponseDtoItemsInnerCurrency interface. - */ -export function instanceOfTopUpsResponseDtoItemsInnerCurrency(value: object): value is TopUpsResponseDtoItemsInnerCurrency { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('symbol' in value) || value['symbol'] === undefined) return false; - if (!('name' in value) || value['name'] === undefined) return false; - if (!('chainId' in value) || value['chainId'] === undefined) return false; - if (!('address' in value) || value['address'] === undefined) return false; - if (!('decimals' in value) || value['decimals'] === undefined) return false; - if (!('isScam' in value) || value['isScam'] === undefined) return false; - if (!('isVerified' in value) || value['isVerified'] === undefined) return false; - return true; -} - -export function TopUpsResponseDtoItemsInnerCurrencyFromJSON(json: any): TopUpsResponseDtoItemsInnerCurrency { - return TopUpsResponseDtoItemsInnerCurrencyFromJSONTyped(json, false); -} - -export function TopUpsResponseDtoItemsInnerCurrencyFromJSONTyped(json: any, ignoreDiscriminator: boolean): TopUpsResponseDtoItemsInnerCurrency { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'symbol': json['symbol'], - 'name': json['name'], - 'chainId': json['chainId'], - 'address': UniversalAddressFromJSON(json['address']), - 'decimals': json['decimals'], - 'isScam': json['isScam'], - 'isVerified': json['isVerified'], - }; -} - -export function TopUpsResponseDtoItemsInnerCurrencyToJSON(json: any): TopUpsResponseDtoItemsInnerCurrency { - return TopUpsResponseDtoItemsInnerCurrencyToJSONTyped(json, false); -} - -export function TopUpsResponseDtoItemsInnerCurrencyToJSONTyped(value?: TopUpsResponseDtoItemsInnerCurrency | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'symbol': value['symbol'], - 'name': value['name'], - 'chainId': value['chainId'], - 'address': UniversalAddressToJSON(value['address']), - 'decimals': value['decimals'], - 'isScam': value['isScam'], - 'isVerified': value['isVerified'], - }; -} - diff --git a/generated-contracts/models/top-ups-response-dto-items-inner.ts b/generated-contracts/models/top-ups-response-dto-items-inner.ts deleted file mode 100644 index 3af2b96..0000000 --- a/generated-contracts/models/top-ups-response-dto-items-inner.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { TopUpsResponseDtoItemsInnerCurrency } from './top-ups-response-dto-items-inner-currency'; -import { - TopUpsResponseDtoItemsInnerCurrencyFromJSON, - TopUpsResponseDtoItemsInnerCurrencyFromJSONTyped, - TopUpsResponseDtoItemsInnerCurrencyToJSON, - TopUpsResponseDtoItemsInnerCurrencyToJSONTyped, -} from './top-ups-response-dto-items-inner-currency'; - -/** - * - * @export - * @interface TopUpsResponseDtoItemsInner - */ -export interface TopUpsResponseDtoItemsInner { - /** - * - * @type {string} - * @memberof TopUpsResponseDtoItemsInner - */ - id: string; - /** - * - * @type {string} - * @memberof TopUpsResponseDtoItemsInner - */ - accountId: string; - /** - * - * @type {string} - * @memberof TopUpsResponseDtoItemsInner - */ - amount: string; - /** - * - * @type {string} - * @memberof TopUpsResponseDtoItemsInner - */ - currencyId: string; - /** - * - * @type {TopUpsResponseDtoItemsInnerCurrency} - * @memberof TopUpsResponseDtoItemsInner - */ - currency: TopUpsResponseDtoItemsInnerCurrency; - /** - * - * @type {number} - * @memberof TopUpsResponseDtoItemsInner - */ - creditsGranted: number; - /** - * - * @type {Date} - * @memberof TopUpsResponseDtoItemsInner - */ - createdAt: Date; -} - -/** - * Check if a given object implements the TopUpsResponseDtoItemsInner interface. - */ -export function instanceOfTopUpsResponseDtoItemsInner(value: object): value is TopUpsResponseDtoItemsInner { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('accountId' in value) || value['accountId'] === undefined) return false; - if (!('amount' in value) || value['amount'] === undefined) return false; - if (!('currencyId' in value) || value['currencyId'] === undefined) return false; - if (!('currency' in value) || value['currency'] === undefined) return false; - if (!('creditsGranted' in value) || value['creditsGranted'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - return true; -} - -export function TopUpsResponseDtoItemsInnerFromJSON(json: any): TopUpsResponseDtoItemsInner { - return TopUpsResponseDtoItemsInnerFromJSONTyped(json, false); -} - -export function TopUpsResponseDtoItemsInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): TopUpsResponseDtoItemsInner { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'accountId': json['accountId'], - 'amount': json['amount'], - 'currencyId': json['currencyId'], - 'currency': TopUpsResponseDtoItemsInnerCurrencyFromJSON(json['currency']), - 'creditsGranted': json['creditsGranted'], - 'createdAt': (new Date(json['createdAt'])), - }; -} - -export function TopUpsResponseDtoItemsInnerToJSON(json: any): TopUpsResponseDtoItemsInner { - return TopUpsResponseDtoItemsInnerToJSONTyped(json, false); -} - -export function TopUpsResponseDtoItemsInnerToJSONTyped(value?: TopUpsResponseDtoItemsInner | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'accountId': value['accountId'], - 'amount': value['amount'], - 'currencyId': value['currencyId'], - 'currency': TopUpsResponseDtoItemsInnerCurrencyToJSON(value['currency']), - 'creditsGranted': value['creditsGranted'], - 'createdAt': value['createdAt'].toISOString(), - }; -} - diff --git a/generated-contracts/models/top-ups-response-dto.ts b/generated-contracts/models/top-ups-response-dto.ts deleted file mode 100644 index 577dca0..0000000 --- a/generated-contracts/models/top-ups-response-dto.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -import type { TopUpsResponseDtoItemsInner } from './top-ups-response-dto-items-inner'; -import { - TopUpsResponseDtoItemsInnerFromJSON, - TopUpsResponseDtoItemsInnerFromJSONTyped, - TopUpsResponseDtoItemsInnerToJSON, - TopUpsResponseDtoItemsInnerToJSONTyped, -} from './top-ups-response-dto-items-inner'; - -/** - * - * @export - * @interface TopUpsResponseDto - */ -export interface TopUpsResponseDto { - /** - * - * @type {number} - * @memberof TopUpsResponseDto - */ - total: number; - /** - * - * @type {number} - * @memberof TopUpsResponseDto - */ - page: number; - /** - * - * @type {number} - * @memberof TopUpsResponseDto - */ - pageSize: number; - /** - * - * @type {Array} - * @memberof TopUpsResponseDto - */ - items: Array; -} - -/** - * Check if a given object implements the TopUpsResponseDto interface. - */ -export function instanceOfTopUpsResponseDto(value: object): value is TopUpsResponseDto { - if (!('total' in value) || value['total'] === undefined) return false; - if (!('page' in value) || value['page'] === undefined) return false; - if (!('pageSize' in value) || value['pageSize'] === undefined) return false; - if (!('items' in value) || value['items'] === undefined) return false; - return true; -} - -export function TopUpsResponseDtoFromJSON(json: any): TopUpsResponseDto { - return TopUpsResponseDtoFromJSONTyped(json, false); -} - -export function TopUpsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): TopUpsResponseDto { - if (json == null) { - return json; - } - return { - - 'total': json['total'], - 'page': json['page'], - 'pageSize': json['pageSize'], - 'items': ((json['items'] as Array).map(TopUpsResponseDtoItemsInnerFromJSON)), - }; -} - -export function TopUpsResponseDtoToJSON(json: any): TopUpsResponseDto { - return TopUpsResponseDtoToJSONTyped(json, false); -} - -export function TopUpsResponseDtoToJSONTyped(value?: TopUpsResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'total': value['total'], - 'page': value['page'], - 'pageSize': value['pageSize'], - 'items': ((value['items'] as Array).map(TopUpsResponseDtoItemsInnerToJSON)), - }; -} - diff --git a/generated-contracts/models/transaction-response-dto.ts b/generated-contracts/models/transaction-response-dto.ts index 82df90d..c14f53a 100644 --- a/generated-contracts/models/transaction-response-dto.ts +++ b/generated-contracts/models/transaction-response-dto.ts @@ -54,7 +54,7 @@ export interface TransactionResponseDto { */ txHash: string; /** - * The unique ID of the currency, ("{chainId}-{contractAddress}") + * The unique ID of the currency, ("{chainId}" or "{chainId}-{contractAddress}") * @type {string} * @memberof TransactionResponseDto */ @@ -199,7 +199,8 @@ export const TransactionResponseDtoOperationTypeEnum = { SetConfig: 'set_config', Claim: 'claim', Payout: 'payout', - Reject: 'reject' + Reject: 'reject', + DappTransaction: 'dapp_transaction' } as const; export type TransactionResponseDtoOperationTypeEnum = typeof TransactionResponseDtoOperationTypeEnum[keyof typeof TransactionResponseDtoOperationTypeEnum]; diff --git a/generated-contracts/models/update-address-book-entry-dto.ts b/generated-contracts/models/update-address-book-entry-dto.ts deleted file mode 100644 index fdb402c..0000000 --- a/generated-contracts/models/update-address-book-entry-dto.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface UpdateAddressBookEntryDto - */ -export interface UpdateAddressBookEntryDto { - /** - * - * @type {string} - * @memberof UpdateAddressBookEntryDto - */ - label?: string; -} - -/** - * Check if a given object implements the UpdateAddressBookEntryDto interface. - */ -export function instanceOfUpdateAddressBookEntryDto(value: object): value is UpdateAddressBookEntryDto { - return true; -} - -export function UpdateAddressBookEntryDtoFromJSON(json: any): UpdateAddressBookEntryDto { - return UpdateAddressBookEntryDtoFromJSONTyped(json, false); -} - -export function UpdateAddressBookEntryDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateAddressBookEntryDto { - if (json == null) { - return json; - } - return { - - 'label': json['label'] == null ? undefined : json['label'], - }; -} - -export function UpdateAddressBookEntryDtoToJSON(json: any): UpdateAddressBookEntryDto { - return UpdateAddressBookEntryDtoToJSONTyped(json, false); -} - -export function UpdateAddressBookEntryDtoToJSONTyped(value?: UpdateAddressBookEntryDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'label': value['label'], - }; -} - diff --git a/generated-contracts/models/update-profile-request-dto.ts b/generated-contracts/models/update-profile-request-dto.ts deleted file mode 100644 index 17bb244..0000000 --- a/generated-contracts/models/update-profile-request-dto.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface UpdateProfileRequestDto - */ -export interface UpdateProfileRequestDto { - /** - * Base currency for conversion - * @type {string} - * @memberof UpdateProfileRequestDto - */ - baseCurrency?: UpdateProfileRequestDtoBaseCurrencyEnum; - /** - * Whether unverified currencies are hidden for the current user by default - * @type {boolean} - * @memberof UpdateProfileRequestDto - */ - hideUnverifiedCurrencies?: boolean; -} - - -/** - * @export - */ -export const UpdateProfileRequestDtoBaseCurrencyEnum = { - Usd: 'usd', - Eur: 'eur', - Cny: 'cny' -} as const; -export type UpdateProfileRequestDtoBaseCurrencyEnum = typeof UpdateProfileRequestDtoBaseCurrencyEnum[keyof typeof UpdateProfileRequestDtoBaseCurrencyEnum]; - - -/** - * Check if a given object implements the UpdateProfileRequestDto interface. - */ -export function instanceOfUpdateProfileRequestDto(value: object): value is UpdateProfileRequestDto { - return true; -} - -export function UpdateProfileRequestDtoFromJSON(json: any): UpdateProfileRequestDto { - return UpdateProfileRequestDtoFromJSONTyped(json, false); -} - -export function UpdateProfileRequestDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateProfileRequestDto { - if (json == null) { - return json; - } - return { - - 'baseCurrency': json['baseCurrency'] == null ? undefined : json['baseCurrency'], - 'hideUnverifiedCurrencies': json['hideUnverifiedCurrencies'] == null ? undefined : json['hideUnverifiedCurrencies'], - }; -} - -export function UpdateProfileRequestDtoToJSON(json: any): UpdateProfileRequestDto { - return UpdateProfileRequestDtoToJSONTyped(json, false); -} - -export function UpdateProfileRequestDtoToJSONTyped(value?: UpdateProfileRequestDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'baseCurrency': value['baseCurrency'], - 'hideUnverifiedCurrencies': value['hideUnverifiedCurrencies'], - }; -} - diff --git a/generated-contracts/models/user-response-dto.ts b/generated-contracts/models/user-response-dto.ts deleted file mode 100644 index 82f7bc8..0000000 --- a/generated-contracts/models/user-response-dto.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface UserResponseDto - */ -export interface UserResponseDto { - /** - * Entity unique identifier - * @type {string} - * @memberof UserResponseDto - */ - id: string; - /** - * Wallet address (Ethereum 0x... or Tron TVM T...) - * @type {string} - * @memberof UserResponseDto - */ - address: string; - /** - * Creation timestamp - * @type {string} - * @memberof UserResponseDto - */ - createdAt: string; - /** - * Last update timestamp - * @type {string} - * @memberof UserResponseDto - */ - updatedAt: string; - /** - * Last login timestamp - * @type {string} - * @memberof UserResponseDto - */ - lastLoginAt: string | null; - /** - * Whether unverified currencies are hidden for the current user by default - * @type {boolean} - * @memberof UserResponseDto - */ - hideUnverifiedCurrencies: boolean; -} - -/** - * Check if a given object implements the UserResponseDto interface. - */ -export function instanceOfUserResponseDto(value: object): value is UserResponseDto { - if (!('id' in value) || value['id'] === undefined) return false; - if (!('address' in value) || value['address'] === undefined) return false; - if (!('createdAt' in value) || value['createdAt'] === undefined) return false; - if (!('updatedAt' in value) || value['updatedAt'] === undefined) return false; - if (!('lastLoginAt' in value) || value['lastLoginAt'] === undefined) return false; - if (!('hideUnverifiedCurrencies' in value) || value['hideUnverifiedCurrencies'] === undefined) return false; - return true; -} - -export function UserResponseDtoFromJSON(json: any): UserResponseDto { - return UserResponseDtoFromJSONTyped(json, false); -} - -export function UserResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UserResponseDto { - if (json == null) { - return json; - } - return { - - 'id': json['id'], - 'address': json['address'], - 'createdAt': json['createdAt'], - 'updatedAt': json['updatedAt'], - 'lastLoginAt': json['lastLoginAt'], - 'hideUnverifiedCurrencies': json['hideUnverifiedCurrencies'], - }; -} - -export function UserResponseDtoToJSON(json: any): UserResponseDto { - return UserResponseDtoToJSONTyped(json, false); -} - -export function UserResponseDtoToJSONTyped(value?: UserResponseDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'id': value['id'], - 'address': value['address'], - 'createdAt': value['createdAt'], - 'updatedAt': value['updatedAt'], - 'lastLoginAt': value['lastLoginAt'], - 'hideUnverifiedCurrencies': value['hideUnverifiedCurrencies'], - }; -} - diff --git a/generated-contracts/models/verify-request-dto.ts b/generated-contracts/models/verify-request-dto.ts deleted file mode 100644 index 9925286..0000000 --- a/generated-contracts/models/verify-request-dto.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * DeFi API (API users) - * API surface available via API key authentication - * - * The version of the OpenAPI document: 1.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - -import { mapValues } from '../runtime'; -/** - * - * @export - * @interface VerifyRequestDto - */ -export interface VerifyRequestDto { - /** - * - * @type {string} - * @memberof VerifyRequestDto - */ - protocol?: VerifyRequestDtoProtocolEnum; - /** - * - * @type {string} - * @memberof VerifyRequestDto - */ - message: string; - /** - * - * @type {string} - * @memberof VerifyRequestDto - */ - signature: string; -} - - -/** - * @export - */ -export const VerifyRequestDtoProtocolEnum = { - Siwe: 'siwe', - Tron: 'tron' -} as const; -export type VerifyRequestDtoProtocolEnum = typeof VerifyRequestDtoProtocolEnum[keyof typeof VerifyRequestDtoProtocolEnum]; - - -/** - * Check if a given object implements the VerifyRequestDto interface. - */ -export function instanceOfVerifyRequestDto(value: object): value is VerifyRequestDto { - if (!('message' in value) || value['message'] === undefined) return false; - if (!('signature' in value) || value['signature'] === undefined) return false; - return true; -} - -export function VerifyRequestDtoFromJSON(json: any): VerifyRequestDto { - return VerifyRequestDtoFromJSONTyped(json, false); -} - -export function VerifyRequestDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): VerifyRequestDto { - if (json == null) { - return json; - } - return { - - 'protocol': json['protocol'] == null ? undefined : json['protocol'], - 'message': json['message'], - 'signature': json['signature'], - }; -} - -export function VerifyRequestDtoToJSON(json: any): VerifyRequestDto { - return VerifyRequestDtoToJSONTyped(json, false); -} - -export function VerifyRequestDtoToJSONTyped(value?: VerifyRequestDto | null, ignoreDiscriminator: boolean = false): any { - if (value == null) { - return value; - } - - return { - - 'protocol': value['protocol'], - 'message': value['message'], - 'signature': value['signature'], - }; -} - diff --git a/jest.config.mjs b/jest.config.mjs new file mode 100644 index 0000000..8b9b0bb --- /dev/null +++ b/jest.config.mjs @@ -0,0 +1,17 @@ +/** @type {import('jest').Config} */ +export default { + testEnvironment: 'node', + roots: ['/src'], + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + tsconfig: 'tsconfig.json', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!viem|@noble|@scure|@adraffy|abitype|ox)'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, +}; diff --git a/package-lock.json b/package-lock.json index 813954e..2b9e602 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,25 @@ { "name": "@b2binpay/defi-sdk", - "version": "auto", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@b2binpay/defi-sdk", - "version": "auto", + "version": "0.0.1", + "license": "MIT", "dependencies": { + "tronweb": "^6.0.2", "viem": "^2.40.3" }, "devDependencies": { "@biomejs/biome": "2.3.2", "@openapitools/openapi-generator-cli": "^2.25.2", + "@types/jest": "^30.0.0", "@types/node": "^24.10.1", "dotenv": "^17.2.3", + "jest": "^30.2.0", + "ts-jest": "^29.4.6", "tsx": "^4.21.0", "typescript": "^5.9.3" }, @@ -29,2107 +34,5398 @@ "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", "license": "MIT" }, - "node_modules/@biomejs/biome": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.2.tgz", - "integrity": "sha512-8e9tzamuDycx7fdrcJ/F/GDZ8SYukc5ud6tDicjjFqURKYFSWMl0H0iXNXZEGmcmNUmABgGuHThPykcM41INgg==", + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, - "license": "MIT OR Apache-2.0", - "bin": { - "biome": "bin/biome" + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { - "node": ">=14.21.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/biome" - }, - "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.3.2", - "@biomejs/cli-darwin-x64": "2.3.2", - "@biomejs/cli-linux-arm64": "2.3.2", - "@biomejs/cli-linux-arm64-musl": "2.3.2", - "@biomejs/cli-linux-x64": "2.3.2", - "@biomejs/cli-linux-x64-musl": "2.3.2", - "@biomejs/cli-win32-arm64": "2.3.2", - "@biomejs/cli-win32-x64": "2.3.2" + "node": ">=6.9.0" } }, - "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.2.tgz", - "integrity": "sha512-4LECm4kc3If0JISai4c3KWQzukoUdpxy4fRzlrPcrdMSRFksR9ZoXK7JBcPuLBmd2SoT4/d7CQS33VnZpgBjew==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", "engines": { - "node": ">=14.21.3" + "node": ">=6.9.0" } }, - "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.2.tgz", - "integrity": "sha512-jNMnfwHT4N3wi+ypRfMTjLGnDmKYGzxVr1EYAPBcauRcDnICFXN81wD6wxJcSUrLynoyyYCdfW6vJHS/IAoTDA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.2.tgz", - "integrity": "sha512-amnqvk+gWybbQleRRq8TMe0rIv7GHss8mFJEaGuEZYWg1Tw14YKOkeo8h6pf1c+d3qR+JU4iT9KXnBKGON4klw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, "engines": { - "node": ">=14.21.3" + "node": ">=6.9.0" } }, - "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.2.tgz", - "integrity": "sha512-2Zz4usDG1GTTPQnliIeNx6eVGGP2ry5vE/v39nT73a3cKN6t5H5XxjcEoZZh62uVZvED7hXXikclvI64vZkYqw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, "engines": { - "node": ">=14.21.3" + "node": ">=6.9.0" } }, - "node_modules/@biomejs/cli-linux-x64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.2.tgz", - "integrity": "sha512-8BG/vRAhFz1pmuyd24FQPhNeueLqPtwvZk6yblABY2gzL2H8fLQAF/Z2OPIc+BPIVPld+8cSiKY/KFh6k81xfA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" } }, - "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.2.tgz", - "integrity": "sha512-gzB19MpRdTuOuLtPpFBGrV3Lq424gHyq2lFj8wfX9tvLMLdmA/R9C7k/mqBp/spcbWuHeIEKgEs3RviOPcWGBA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", "engines": { - "node": ">=14.21.3" + "node": ">=6.9.0" } }, - "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.2.tgz", - "integrity": "sha512-lCruqQlfWjhMlOdyf5pDHOxoNm4WoyY2vZ4YN33/nuZBRstVDuqPPjS0yBkbUlLEte11FbpW+wWSlfnZfSIZvg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, "engines": { - "node": ">=14.21.3" + "node": ">=6.9.0" } }, - "node_modules/@biomejs/cli-win32-x64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.2.tgz", - "integrity": "sha512-6Ee9P26DTb4D8sN9nXxgbi9Dw5vSOfH98M7UlmkjKB2vtUbrRqCbZiNfryGiwnPIpd6YUoTl7rLVD2/x1CyEHQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, "engines": { - "node": ">=14.21.3" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@borewit/text-codec": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz", - "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", - "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", - "cpu": [ - "ppc64" - ], + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], "engines": { - "node": ">=18" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", - "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", - "cpu": [ - "arm" - ], + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=18" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", - "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=18" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", - "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", - "cpu": [ - "x64" - ], + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", - "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", - "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", - "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", - "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", - "cpu": [ - "x64" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", - "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", - "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", - "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", - "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", - "cpu": [ - "loong64" - ], + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", - "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", - "cpu": [ - "mips64el" - ], + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", - "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", - "cpu": [ - "ppc64" - ], + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", - "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", - "cpu": [ - "riscv64" - ], + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", - "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", - "cpu": [ - "s390x" - ], + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", - "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", - "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", - "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", - "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", - "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", - "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", - "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", - "cpu": [ - "x64" - ], - "dev": true, + "node_modules/@babel/runtime": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "license": "MIT", - "optional": true, - "os": [ - "sunos" + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@biomejs/biome": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.2.tgz", + "integrity": "sha512-8e9tzamuDycx7fdrcJ/F/GDZ8SYukc5ud6tDicjjFqURKYFSWMl0H0iXNXZEGmcmNUmABgGuHThPykcM41INgg==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.3.2", + "@biomejs/cli-darwin-x64": "2.3.2", + "@biomejs/cli-linux-arm64": "2.3.2", + "@biomejs/cli-linux-arm64-musl": "2.3.2", + "@biomejs/cli-linux-x64": "2.3.2", + "@biomejs/cli-linux-x64-musl": "2.3.2", + "@biomejs/cli-win32-arm64": "2.3.2", + "@biomejs/cli-win32-x64": "2.3.2" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.2.tgz", + "integrity": "sha512-4LECm4kc3If0JISai4c3KWQzukoUdpxy4fRzlrPcrdMSRFksR9ZoXK7JBcPuLBmd2SoT4/d7CQS33VnZpgBjew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" ], "engines": { - "node": ">=18" + "node": ">=14.21.3" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", - "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.2.tgz", + "integrity": "sha512-jNMnfwHT4N3wi+ypRfMTjLGnDmKYGzxVr1EYAPBcauRcDnICFXN81wD6wxJcSUrLynoyyYCdfW6vJHS/IAoTDA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.2.tgz", + "integrity": "sha512-amnqvk+gWybbQleRRq8TMe0rIv7GHss8mFJEaGuEZYWg1Tw14YKOkeo8h6pf1c+d3qR+JU4iT9KXnBKGON4klw==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.2.tgz", + "integrity": "sha512-2Zz4usDG1GTTPQnliIeNx6eVGGP2ry5vE/v39nT73a3cKN6t5H5XxjcEoZZh62uVZvED7hXXikclvI64vZkYqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.2.tgz", + "integrity": "sha512-8BG/vRAhFz1pmuyd24FQPhNeueLqPtwvZk6yblABY2gzL2H8fLQAF/Z2OPIc+BPIVPld+8cSiKY/KFh6k81xfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.2.tgz", + "integrity": "sha512-gzB19MpRdTuOuLtPpFBGrV3Lq424gHyq2lFj8wfX9tvLMLdmA/R9C7k/mqBp/spcbWuHeIEKgEs3RviOPcWGBA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.2.tgz", + "integrity": "sha512-lCruqQlfWjhMlOdyf5pDHOxoNm4WoyY2vZ4YN33/nuZBRstVDuqPPjS0yBkbUlLEte11FbpW+wWSlfnZfSIZvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=18" + "node": ">=14.21.3" } }, - "node_modules/@esbuild/win32-ia32": { + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.2.tgz", + "integrity": "sha512-6Ee9P26DTb4D8sN9nXxgbi9Dw5vSOfH98M7UlmkjKB2vtUbrRqCbZiNfryGiwnPIpd6YUoTl7rLVD2/x1CyEHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@borewit/text-codec": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz", + "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", - "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", "cpu": [ - "ia32" + "ppc64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "aix" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/win32-x64": { + "node_modules/@esbuild/android-arm": { "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", - "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", "cpu": [ - "x64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "android" ], "engines": { "node": ">=18" } }, - "node_modules/@inquirer/external-editor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", - "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "chardet": "^2.1.1", - "iconv-lite": "^0.7.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-6.0.0.tgz", + "integrity": "sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^1.1.6", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.10.7", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "figures": "^3.2.0", + "mute-stream": "^1.0.0", + "run-async": "^3.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/core/node_modules/@types/node": { + "version": "20.19.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.35.tgz", + "integrity": "sha512-Uarfe6J91b9HAUXxjvSOdiO2UPOKLm07Q1oh0JHxoZ1y8HoqxDAu3gVrsrOHeiio0kSsoVBt4wFrKOm0dKxVPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@inquirer/core/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@inquirer/core/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@inquirer/select": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-1.3.3.tgz", + "integrity": "sha512-RzlRISXWqIKEf83FDC9ZtJ3JvuK1l7aGpretf41BCWYrvla2wU8W8MTRNMiPrPJ+1SIqrRC1nZdZ60hD9hRXLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^6.0.0", + "@inquirer/type": "^1.1.6", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "figures": "^3.2.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", + "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", + "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.2.0", + "@jest/pattern": "30.0.1", + "@jest/reporters": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.2.0", + "jest-config": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-resolve-dependencies": "30.2.0", + "jest-runner": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "jest-watcher": "30.2.0", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", + "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-mock": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "30.2.0", + "jest-snapshot": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", + "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@sinonjs/fake-timers": "^13.0.0", + "@types/node": "*", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", + "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/types": "30.2.0", + "jest-mock": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", + "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "@types/node": "*", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^5.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "slash": "^3.0.0", + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@jest/reporters/node_modules/minimatch": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.8.tgz", + "integrity": "sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", + "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", + "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.2.0", + "@jest/types": "30.2.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", + "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", + "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "micromatch": "^4.0.8", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lukeed/csprng": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", + "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@nestjs/axios": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", + "integrity": "sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "axios": "^1.3.1", + "rxjs": "^7.0.0" + } + }, + "node_modules/@nestjs/common": { + "version": "11.1.17", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.17.tgz", + "integrity": "sha512-hLODw5Abp8OQgA+mUO4tHou4krKgDtUcM9j5Ihxncst9XeyxYBTt2bwZm4e4EQr5E352S4Fyy6V3iFx9ggxKAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-type": "21.3.2", + "iterare": "1.2.1", + "load-esm": "1.0.3", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "class-transformer": ">=0.4.1", + "class-validator": ">=0.13.2", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, + "node_modules/@nestjs/core": { + "version": "11.1.18", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.18.tgz", + "integrity": "sha512-wR3DtGyk/LUAiPtbXDuWJJwVkWElKBY0sqnTzf9d4uM3+X18FRZhK7WFc47czsIGOdWuRsMeLYV+1Z9dO4zDEQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@nuxt/opencollective": "0.4.1", + "fast-safe-stringify": "2.1.1", + "iterare": "1.2.1", + "path-to-regexp": "8.4.2", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "engines": { + "node": ">= 20" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/microservices": "^11.0.0", + "@nestjs/platform-express": "^11.0.0", + "@nestjs/websockets": "^11.0.0", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/platform-express": { + "optional": true + }, + "@nestjs/websockets": { + "optional": true + } + } + }, + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nuxt/opencollective": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", + "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + }, + "bin": { + "opencollective": "bin/opencollective.js" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0", + "npm": ">=5.10.0" + } + }, + "node_modules/@nuxtjs/opencollective": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz", + "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.0", + "node-fetch": "^2.6.1" + }, + "bin": { + "opencollective": "bin/opencollective.js" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/@nuxtjs/opencollective/node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openapitools/openapi-generator-cli": { + "version": "2.31.1", + "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.31.1.tgz", + "integrity": "sha512-dPE+COjNLLTHFQ1lddUvpo+J8YQB1RD3/NVRJ3K+1hPZnyuxCURgOCmr7mXgHEyHmzWH8dKXWm/pD170iVR0vw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@inquirer/select": "1.3.3", + "@nestjs/axios": "4.0.1", + "@nestjs/common": "11.1.17", + "@nestjs/core": "11.1.18", + "@nuxtjs/opencollective": "0.3.2", + "axios": "^1.14.0", + "chalk": "4.1.2", + "commander": "8.3.0", + "compare-versions": "6.1.1", + "concurrently": "9.2.1", + "console.table": "0.10.0", + "fs-extra": "11.3.4", + "glob": "13.0.6", + "proxy-agent": "6.5.0", + "reflect-metadata": "0.2.2", + "rxjs": "7.8.2", + "tslib": "2.8.1" + }, + "bin": { + "openapi-generator-cli": "main.js" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/openapi_generator" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^30.0.0", + "pretty-format": "^30.0.0" + } + }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/abitype": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.1.0.tgz", + "integrity": "sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", + "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/axios/node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/babel-jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", + "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "30.2.0", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "dev": true, + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz", + "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel__core": "^7.20.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz", + "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/basic-ftp": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.0.tgz", + "integrity": "sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001774", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz", + "integrity": "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/console.table": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz", + "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "easy-table": "1.1.0" + }, + "engines": { + "node": "> 0.10" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", + "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/easy-table": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", + "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "wcwidth": ">=1.0.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.302", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", + "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.0", + "@esbuild/android-arm": "0.27.0", + "@esbuild/android-arm64": "0.27.0", + "@esbuild/android-x64": "0.27.0", + "@esbuild/darwin-arm64": "0.27.0", + "@esbuild/darwin-x64": "0.27.0", + "@esbuild/freebsd-arm64": "0.27.0", + "@esbuild/freebsd-x64": "0.27.0", + "@esbuild/linux-arm": "0.27.0", + "@esbuild/linux-arm64": "0.27.0", + "@esbuild/linux-ia32": "0.27.0", + "@esbuild/linux-loong64": "0.27.0", + "@esbuild/linux-mips64el": "0.27.0", + "@esbuild/linux-ppc64": "0.27.0", + "@esbuild/linux-riscv64": "0.27.0", + "@esbuild/linux-s390x": "0.27.0", + "@esbuild/linux-x64": "0.27.0", + "@esbuild/netbsd-arm64": "0.27.0", + "@esbuild/netbsd-x64": "0.27.0", + "@esbuild/openbsd-arm64": "0.27.0", + "@esbuild/openbsd-x64": "0.27.0", + "@esbuild/openharmony-arm64": "0.27.0", + "@esbuild/sunos-x64": "0.27.0", + "@esbuild/win32-arm64": "0.27.0", + "@esbuild/win32-ia32": "0.27.0", + "@esbuild/win32-x64": "0.27.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers": { + "version": "6.13.5", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.5.tgz", + "integrity": "sha512-+knKNieu5EKRThQJWwqaJ10a6HE9sSehGeqWN65//wE7j47ZpFhKAnHB/JJFibwwg61I/koxaPsXbXpD/skNOQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" } - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, + ], "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, "engines": { - "node": "20 || >=22" + "node": ">=14.0.0" } }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, + "node_modules/ethers/node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "license": "MIT" + }, + "node_modules/ethers/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", "license": "MIT", "dependencies": { - "@isaacs/balanced-match": "^4.0.1" + "@noble/hashes": "1.3.2" }, - "engines": { - "node": "20 || >=22" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@lukeed/csprng": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", - "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", - "dev": true, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@nestjs/axios": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", - "integrity": "sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==", - "dev": true, + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", "license": "MIT", - "peerDependencies": { - "@nestjs/common": "^10.0.0 || ^11.0.0", - "axios": "^1.3.1", - "rxjs": "^7.0.0" + "dependencies": { + "undici-types": "~6.19.2" } }, - "node_modules/@nestjs/common": { - "version": "11.1.9", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.9.tgz", - "integrity": "sha512-zDntUTReRbAThIfSp3dQZ9kKqI+LjgLp5YZN5c1bgNRDuoeLySAoZg46Bg1a+uV8TMgIRziHocglKGNzr6l+bQ==", - "dev": true, + "node_modules/ethers/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, + "node_modules/ethers/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/ethers/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "license": "MIT", - "dependencies": { - "file-type": "21.1.0", - "iterare": "1.2.1", - "load-esm": "1.0.3", - "tslib": "2.8.1", - "uid": "2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" + "engines": { + "node": ">=10.0.0" }, "peerDependencies": { - "class-transformer": ">=0.4.1", - "class-validator": ">=0.13.2", - "reflect-metadata": "^0.1.12 || ^0.2.0", - "rxjs": "^7.1.0" + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { - "class-transformer": { + "bufferutil": { "optional": true }, - "class-validator": { + "utf-8-validate": { "optional": true } } }, - "node_modules/@nestjs/core": { - "version": "11.1.9", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.9.tgz", - "integrity": "sha512-a00B0BM4X+9z+t3UxJqIZlemIwCQdYoPKrMcM+ky4z3pkqqG1eTWexjs+YXpGObnLnjtMPVKWlcZHp3adDYvUw==", + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "hasInstallScript": true, "license": "MIT", "dependencies": { - "@nuxt/opencollective": "0.4.1", - "fast-safe-stringify": "2.1.1", - "iterare": "1.2.1", - "path-to-regexp": "8.3.0", - "tslib": "2.8.1", - "uid": "2.0.2" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">= 20" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nest" - }, - "peerDependencies": { - "@nestjs/common": "^11.0.0", - "@nestjs/microservices": "^11.0.0", - "@nestjs/platform-express": "^11.0.0", - "@nestjs/websockets": "^11.0.0", - "reflect-metadata": "^0.1.12 || ^0.2.0", - "rxjs": "^7.1.0" - }, - "peerDependenciesMeta": { - "@nestjs/microservices": { - "optional": true - }, - "@nestjs/platform-express": { - "optional": true - }, - "@nestjs/websockets": { - "optional": true - } + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@noble/ciphers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", - "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "dev": true, "license": "MIT", "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "1.8.0" + "escape-string-regexp": "^1.0.5" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=8" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/file-type": { + "version": "21.3.2", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.2.tgz", + "integrity": "sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==", + "dev": true, "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=20" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/@nuxt/opencollective": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", - "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { - "consola": "^3.2.3" - }, - "bin": { - "opencollective": "bin/opencollective.js" + "to-regex-range": "^5.0.1" }, "engines": { - "node": "^14.18.0 || >=16.10.0", - "npm": ">=5.10.0" + "node": ">=8" } }, - "node_modules/@nuxtjs/opencollective": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz", - "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==", + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.0", - "node-fetch": "^2.6.1" - }, - "bin": { - "opencollective": "bin/opencollective.js" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" + "node": ">=8" } }, - "node_modules/@nuxtjs/opencollective/node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", - "dev": true, - "license": "MIT" + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } }, - "node_modules/@openapitools/openapi-generator-cli": { - "version": "2.25.2", - "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.25.2.tgz", - "integrity": "sha512-TXElbW1NXCy0EECXiO5AD2ZzT1dmaCs41Z8t3pBUGaJf8zgF/Lm0P6GRhVEpw29iHBNjZcy8nrgQ1acUfuCdng==", + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", + "license": "ISC", "dependencies": { - "@nestjs/axios": "4.0.1", - "@nestjs/common": "11.1.9", - "@nestjs/core": "11.1.9", - "@nuxtjs/opencollective": "0.3.2", - "axios": "1.13.2", - "chalk": "4.1.2", - "commander": "8.3.0", - "compare-versions": "6.1.1", - "concurrently": "9.2.1", - "console.table": "0.10.0", - "fs-extra": "11.3.2", - "glob": "13.0.0", - "inquirer": "8.2.7", - "proxy-agent": "6.5.0", - "reflect-metadata": "0.2.2", - "rxjs": "7.8.2", - "tslib": "2.8.1" - }, - "bin": { - "openapi-generator-cli": "main.js" + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=16" + "node": ">=14" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/openapi_generator" - } - }, - "node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">= 6" } }, - "node_modules/@tokenizer/inflate": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.3.1.tgz", - "integrity": "sha512-4oeoZEBQdLdt5WmP/hx1KZ6D3/Oid/0cUb2nk4F0pTDAWy+KCH3/EnAkZF/bvckWo8I33EqBm01lIPgmgc8rCA==", + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.4.1", - "fflate": "^0.8.2", - "token-types": "^6.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "node": ">=14.14" } }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/abitype": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.1.0.tgz", - "integrity": "sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3.22.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", "engines": { - "node": ">= 14" + "node": ">=6.9.0" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">= 0.4" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "dev": true, "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", "dev": true, "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, "engines": { - "node": ">=10.0.0" + "node": ">= 14" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } + "node_modules/google-protobuf": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz", + "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==", + "license": "(BSD-3-Clause AND Apache-2.0)" }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" }, "engines": { - "node": ">=10" + "node": ">=0.4.7" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "node_modules/chardet": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", - "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, "engines": { "node": ">=8" } }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 10" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">= 0.4" } }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } + "license": "MIT" }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=7.0.0" + "node": ">= 14" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" + "agent-base": "^7.1.2", + "debug": "4" }, "engines": { - "node": ">= 0.8" + "node": ">= 14" } }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">= 12" + "node": ">=10.17.0" } }, - "node_modules/compare-versions": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", - "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, - "license": "MIT" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" }, - "node_modules/concurrently": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", - "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "4.1.2", - "rxjs": "7.8.2", - "shell-quote": "1.8.3", - "supports-color": "8.1.1", - "tree-kill": "1.2.2", - "yargs": "17.7.2" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" }, "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" - } - }, - "node_modules/concurrently/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" + "import-local-fixture": "fixtures/cli.js" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { - "node": "^14.18.0 || >=16.10.0" + "node": ">=0.8.19" } }, - "node_modules/console.table": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz", - "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "easy-table": "1.1.0" - }, - "engines": { - "node": "> 0.10" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } + "license": "ISC" }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "dev": true, "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 12" } }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, "engines": { - "node": ">= 14" + "node": ">=8" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.4.0" + "node": ">=6" } }, - "node_modules/dotenv": { - "version": "17.2.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", - "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" + "node": ">=0.12.0" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/easy-table": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", - "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, + "license": "ISC" + }, + "node_modules/isows": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", + "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], "license": "MIT", - "optionalDependencies": { - "wcwidth": ">=1.0.1" + "peerDependencies": { + "ws": "*" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/esbuild": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", - "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" }, "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.0", - "@esbuild/android-arm": "0.27.0", - "@esbuild/android-arm64": "0.27.0", - "@esbuild/android-x64": "0.27.0", - "@esbuild/darwin-arm64": "0.27.0", - "@esbuild/darwin-x64": "0.27.0", - "@esbuild/freebsd-arm64": "0.27.0", - "@esbuild/freebsd-x64": "0.27.0", - "@esbuild/linux-arm": "0.27.0", - "@esbuild/linux-arm64": "0.27.0", - "@esbuild/linux-ia32": "0.27.0", - "@esbuild/linux-loong64": "0.27.0", - "@esbuild/linux-mips64el": "0.27.0", - "@esbuild/linux-ppc64": "0.27.0", - "@esbuild/linux-riscv64": "0.27.0", - "@esbuild/linux-s390x": "0.27.0", - "@esbuild/linux-x64": "0.27.0", - "@esbuild/netbsd-arm64": "0.27.0", - "@esbuild/netbsd-x64": "0.27.0", - "@esbuild/openbsd-arm64": "0.27.0", - "@esbuild/openbsd-x64": "0.27.0", - "@esbuild/openharmony-arm64": "0.27.0", - "@esbuild/sunos-x64": "0.27.0", - "@esbuild/win32-arm64": "0.27.0", - "@esbuild/win32-ia32": "0.27.0", - "@esbuild/win32-x64": "0.27.0" + "node": ">=10" } }, - "node_modules/escalade": { + "node_modules/istanbul-reports": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/iterare": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", + "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", "dev": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=0.8.0" + "node": ">=6" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, - "license": "BSD-2-Clause", + "license": "BlueOak-1.0.0", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" + "@isaacs/cliui": "^8.0.2" }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" }, "optionalDependencies": { - "source-map": "~0.6.1" + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz", + "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "dependencies": { + "@jest/core": "30.2.0", + "@jest/types": "30.2.0", + "import-local": "^3.2.0", + "jest-cli": "30.2.0" + }, "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "jest": "bin/jest.js" }, "engines": { - "node": ">=4" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/jest-changed-files": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz", + "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "dependencies": { + "execa": "^5.1.1", + "jest-util": "30.2.0", + "p-limit": "^3.1.0" + }, "engines": { - "node": ">=4.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/jest-circus": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", + "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "co": "^4.6.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "p-limit": "^3.1.0", + "pretty-format": "30.2.0", + "pure-rand": "^7.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-cli": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz", + "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "yargs": "^17.7.2" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=0.10.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true, - "license": "MIT" - }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "node_modules/jest-config": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", + "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.0.1", + "@jest/test-sequencer": "30.2.0", + "@jest/types": "30.2.0", + "babel-jest": "30.2.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-circus": "30.2.0", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-runner": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "micromatch": "^4.0.8", + "parse-json": "^5.2.0", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } + } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "node_modules/jest-config/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "escape-string-regexp": "^1.0.5" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": ">=8" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/file-type": { - "version": "21.1.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.1.0.tgz", - "integrity": "sha512-boU4EHmP3JXkwDo4uhyBhTt5pPstxB6eEXKJBu2yu2l7aAMMm7QQYQEzssJmKReZYrFdFOJS8koVo6bXIBGDqA==", + "node_modules/jest-config/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "license": "MIT", + "license": "ISC" + }, + "node_modules/jest-config/node_modules/minimatch": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.8.tgz", + "integrity": "sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw==", + "dev": true, + "license": "ISC", "dependencies": { - "@tokenizer/inflate": "^0.3.1", - "strtok3": "^10.3.1", - "token-types": "^6.0.0", - "uint8array-extras": "^1.4.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=20" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "node_modules/jest-config/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, "engines": { - "node": ">=4.0" + "node": ">=16 || 14 >=14.18" }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "node_modules/jest-diff": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", + "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", "dev": true, "license": "MIT", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.2.0" }, "engines": { - "node": ">= 6" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/fs-extra": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", - "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "node_modules/jest-docblock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", + "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "detect-newline": "^3.1.0" }, "engines": { - "node": ">=14.14" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/jest-each": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz", + "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "jest-util": "30.2.0", + "pretty-format": "30.2.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/jest-environment-node": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", + "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-mock": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "node_modules/jest-haste-map": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", + "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" + "@jest/types": "30.2.0", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "micromatch": "^4.0.8", + "walker": "^1.0.8" }, "engines": { - "node": ">= 0.4" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "fsevents": "^2.3.3" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "node_modules/jest-leak-detector": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz", + "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==", "dev": true, "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "@jest/get-type": "30.1.0", + "pretty-format": "30.2.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/get-tsconfig": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "node_modules/jest-matcher-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", + "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", "dev": true, "license": "MIT", "dependencies": { - "resolve-pkg-maps": "^1.0.0" + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.2.0", + "pretty-format": "30.2.0" }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/get-uri": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", - "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "node_modules/jest-message-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", + "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", "dev": true, "license": "MIT", "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4" + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.2.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" }, "engines": { - "node": ">= 14" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "node_modules/jest-mock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", + "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-util": "30.2.0" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=6" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "node_modules/jest-resolve": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", + "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "node_modules/jest-resolve-dependencies": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", + "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.3" + "jest-regex-util": "30.0.1", + "jest-snapshot": "30.2.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/jest-runner": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz", + "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==", "dev": true, "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "@jest/console": "30.2.0", + "@jest/environment": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-leak-detector": "30.2.0", + "jest-message-util": "30.2.0", + "jest-resolve": "30.2.0", + "jest-runtime": "30.2.0", + "jest-util": "30.2.0", + "jest-watcher": "30.2.0", + "jest-worker": "30.2.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz", + "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==", "dev": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" + "@jest/environment": "30.2.0", + "@jest/fake-timers": "30.2.0", + "@jest/globals": "30.2.0", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": ">= 14" + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "node_modules/jest-runtime/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "license": "MIT", + "license": "ISC" + }, + "node_modules/jest-runtime/node_modules/minimatch": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.8.tgz", + "integrity": "sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw==", + "dev": true, + "license": "ISC", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">= 14" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "node_modules/jest-runtime/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.18" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "node_modules/jest-snapshot": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", + "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-diff": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "pretty-format": "30.2.0", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "node_modules/inquirer": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", - "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "node_modules/jest-validate": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz", + "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/external-editor": "^1.0.0", - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^6.0.1" + "@jest/get-type": "30.1.0", + "@jest/types": "30.2.0", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", + "leven": "^3.1.0", + "pretty-format": "30.2.0" }, "engines": { - "node": ">=12.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 12" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/jest-watcher": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz", + "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==", "dev": true, "license": "MIT", + "dependencies": { + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "jest-util": "30.2.0", + "string-length": "^4.0.2" + }, "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "node_modules/jest-worker": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", + "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", "dev": true, "license": "MIT", + "dependencies": { + "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.2.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.1.1" + }, "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/isows": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", - "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, "license": "MIT", - "peerDependencies": { - "ws": "*" + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/iterare": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", - "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, - "license": "ISC", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, "engines": { "node": ">=6" } @@ -2147,6 +5443,23 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, "node_modules/load-esm": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz", @@ -2167,22 +5480,44 @@ "node": ">=13.2.0" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true, "license": "MIT" }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "semver": "^7.5.3" }, "engines": { "node": ">=10" @@ -2191,31 +5526,70 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lru-cache": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", - "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": "20 || >=22" + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" } }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -2225,7 +5599,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -2245,27 +5618,37 @@ } }, "node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -2278,11 +5661,44 @@ "license": "MIT" }, "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, - "license": "ISC" + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" }, "node_modules/netmask": { "version": "2.0.2", @@ -2315,6 +5731,53 @@ } } }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -2327,62 +5790,93 @@ "engines": { "node": ">=6" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ox": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.9.6.tgz", + "integrity": "sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.11.0", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "1.9.1", + "@noble/hashes": "^1.8.0", + "@scure/bip32": "^1.7.0", + "@scure/bip39": "^1.6.0", + "abitype": "^1.0.9", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" + "p-try": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ox": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.9.6.tgz", - "integrity": "sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.11.0", - "@noble/ciphers": "^1.3.0", - "@noble/curves": "1.9.1", - "@noble/hashes": "^1.8.0", - "@scure/bip32": "^1.7.0", - "@scure/bip39": "^1.6.0", - "abitype": "^1.0.9", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": ">=6" } }, "node_modules/pac-proxy-agent": { @@ -2419,10 +5913,66 @@ "node": ">= 14" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -2430,16 +5980,16 @@ "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "dev": true, "license": "MIT", "funding": { @@ -2447,6 +5997,77 @@ "url": "https://opencollective.com/express" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/proxy-agent": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", @@ -2484,20 +6105,29 @@ "dev": true, "license": "MIT" }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/pure-rand": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/reflect-metadata": { "version": "0.2.2", @@ -2506,6 +6136,12 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2516,34 +6152,43 @@ "node": ">=0.10.0" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, "engines": { "node": ">=8" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, "license": "MIT", "engines": { @@ -2560,33 +6205,38 @@ "tslib": "^2.1.0" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, "node_modules/shell-quote": { "version": "1.8.3", @@ -2608,6 +6258,16 @@ "dev": true, "license": "ISC" }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -2655,19 +6315,63 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", - "optional": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "~5.2.0" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/string-width": { @@ -2685,7 +6389,37 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -2698,10 +6432,43 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strtok3": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", - "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", "dev": true, "license": "MIT", "dependencies": { @@ -2728,21 +6495,118 @@ "node": ">=8" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "node_modules/synckit": { + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/token-types": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.1.tgz", - "integrity": "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", "dev": true, "license": "MIT", "dependencies": { - "@borewit/text-codec": "^0.1.0", + "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" }, @@ -2771,6 +6635,117 @@ "tree-kill": "cli.js" } }, + "node_modules/tronweb": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tronweb/-/tronweb-6.0.2.tgz", + "integrity": "sha512-I8MfenbmGTbDYhr/d/SMH1QGMv2ISHro23hL8TGoDjt2oYMcekFX76rjnEBdfe/P/roqwrZs1nGRdeftn3iZQw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.0.0", + "axios": "^1.8.3", + "bignumber.js": "^9.0.1", + "ethereum-cryptography": "^2.1.3", + "ethers": "^6.13.4", + "eventemitter3": "^3.1.0", + "google-protobuf": "^3.21.4", + "semver": "^5.6.0", + "validator": "^13.7.0" + } + }, + "node_modules/tronweb/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "license": "MIT" + }, + "node_modules/tronweb/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ts-jest": { + "version": "29.4.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", + "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.3", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -2798,6 +6773,16 @@ "fsevents": "~2.3.3" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -2825,6 +6810,20 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/uid": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", @@ -2868,12 +6867,95 @@ "node": ">= 10.0.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", "dev": true, - "license": "MIT" + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validator": { + "version": "13.15.23", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz", + "integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } }, "node_modules/viem": { "version": "2.40.3", @@ -2905,12 +6987,23 @@ } } }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { "defaults": "^1.0.3" } @@ -2933,6 +7026,29 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -2948,6 +7064,59 @@ "node": ">=8" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ws": { "version": "8.18.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", @@ -2979,6 +7148,13 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -3007,6 +7183,19 @@ "engines": { "node": ">=12" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 8a40412..df892fd 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "url": "https://github.com/b2binpay/defi-sdk-nodejs/issues" }, "scripts": { + "test": "jest", "build": "tsc -p tsconfig.build.json", "lint": "biome check", "lint:fix": "biome check --fix", @@ -26,16 +27,29 @@ "example:claim-deposits": "tsx examples/claim-deposits.ts", "example:queue-sign": "tsx examples/queue-sign.ts", "example:queue-execute": "tsx examples/queue-execute.ts", - "example:queue-execute-batch": "tsx examples/queue-execute-batch.ts" + "example:queue-execute-batch": "tsx examples/queue-execute-batch.ts", + "example:evm-full-flow": "tsx examples/evm-full-flow.ts", + "example:tron-get-account-info": "tsx examples/tron-get-account-info.ts", + "example:tron-create-invoice": "tsx examples/tron-create-invoice.ts", + "example:tron-create-payout": "tsx examples/tron-create-payout.ts", + "example:tron-claim-deposits": "tsx examples/tron-claim-deposits.ts", + "example:tron-queue-sign": "tsx examples/tron-queue-sign.ts", + "example:tron-queue-execute": "tsx examples/tron-queue-execute.ts", + "example:tron-queue-execute-batch": "tsx examples/tron-queue-execute-batch.ts", + "example:tron-full-flow": "tsx examples/tron-full-flow.ts" }, "dependencies": { + "tronweb": "^6.0.2", "viem": "^2.40.3" }, "devDependencies": { "@biomejs/biome": "2.3.2", "@openapitools/openapi-generator-cli": "^2.25.2", + "@types/jest": "^30.0.0", "@types/node": "^24.10.1", "dotenv": "^17.2.3", + "jest": "^30.2.0", + "ts-jest": "^29.4.6", "tsx": "^4.21.0", "typescript": "^5.9.3" }, diff --git a/src/abi-provider.ts b/src/abi-provider.ts new file mode 100644 index 0000000..90a14d7 --- /dev/null +++ b/src/abi-provider.ts @@ -0,0 +1,115 @@ +import * as fs from 'node:fs/promises'; +import * as path from 'node:path'; +import type { Abi } from 'viem'; +import type { SmartContractVersionsApi } from '../generated-contracts'; + +export interface AbiCacheEntry { + abi: Abi; + version: string; +} + +export class AbiProvider { + private static readonly SAFE_VERSION_ID_PATTERN = /^[a-zA-Z0-9._-]+$/; + + private readonly memoryCache = new Map(); + private readonly inFlight = new Map>(); + private readonly api: SmartContractVersionsApi; + private readonly cacheDir: string | null; + + constructor(api: SmartContractVersionsApi, cacheDir?: string) { + this.api = api; + this.cacheDir = cacheDir ?? null; + } + + async getAbi(versionId: string): Promise { + const cached = this.memoryCache.get(versionId); + if (cached) { + return cached; + } + + const pending = this.inFlight.get(versionId); + if (pending) { + return pending; + } + + const promise = this.fetchAbi(versionId); + this.inFlight.set(versionId, promise); + + try { + return await promise; + } finally { + this.inFlight.delete(versionId); + } + } + + private async fetchAbi(versionId: string): Promise { + const fromDisk = await this.readFromDisk(versionId); + if (fromDisk) { + this.memoryCache.set(versionId, fromDisk); + return fromDisk; + } + + const response = await this.api.publicSmartContractVersionsControllerGetByVersionIdV1({ + versionId, + }); + + if (!Array.isArray(response.accountAbi)) { + throw new Error(`Invalid ABI received from API for version "${versionId}": expected an array.`); + } + + const entry: AbiCacheEntry = { + abi: response.accountAbi as Abi, + version: response.version, + }; + + this.memoryCache.set(versionId, entry); + await this.writeToDisk(versionId, entry); + + return entry; + } + + private sanitizeVersionId(versionId: string): string | null { + if (!AbiProvider.SAFE_VERSION_ID_PATTERN.test(versionId)) { + return null; + } + return versionId; + } + + private async readFromDisk(versionId: string): Promise { + if (!this.cacheDir) { + return null; + } + + const safeId = this.sanitizeVersionId(versionId); + if (!safeId) { + return null; + } + + try { + const filePath = path.join(this.cacheDir, `${safeId}.json`); + const data = await fs.readFile(filePath, 'utf-8'); + return JSON.parse(data) as AbiCacheEntry; + } catch { + return null; + } + } + + private async writeToDisk(versionId: string, entry: AbiCacheEntry): Promise { + if (!this.cacheDir) { + return; + } + + const safeId = this.sanitizeVersionId(versionId); + if (!safeId) { + return; + } + + try { + await fs.mkdir(this.cacheDir, { recursive: true }); + const filePath = path.join(this.cacheDir, `${safeId}.json`); + await fs.writeFile(filePath, JSON.stringify(entry), 'utf-8'); + } catch { + // Gracefully degrade if filesystem is unavailable + } + } +} diff --git a/src/abi/index.ts b/src/abi/index.ts deleted file mode 100644 index e9f06b5..0000000 --- a/src/abi/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - MULTI_SIG_WALLET_ABI, - type MultiSigWalletAbi, -} from './multi-sig-wallet'; diff --git a/src/abi/multi-sig-wallet.ts b/src/abi/multi-sig-wallet.ts deleted file mode 100644 index a45c9be..0000000 --- a/src/abi/multi-sig-wallet.ts +++ /dev/null @@ -1,706 +0,0 @@ -import type { Abi } from 'viem'; - -export const MULTI_SIG_WALLET_ABI = [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [], - name: 'Create2EmptyBytecode', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'DuplicateOwner', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'DuplicateSignature', - type: 'error', - }, - { - inputs: [], - name: 'ECDSAInvalidSignature', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'length', - type: 'uint256', - }, - ], - name: 'ECDSAInvalidSignatureLength', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 's', - type: 'bytes32', - }, - ], - name: 'ECDSAInvalidSignatureS', - type: 'error', - }, - { - inputs: [], - name: 'FailedCall', - type: 'error', - }, - { - inputs: [], - name: 'FailedDeployment', - type: 'error', - }, - { - inputs: [], - name: 'FailedDeployment', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'balance', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'needed', - type: 'uint256', - }, - ], - name: 'InsufficientBalance', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'signatures', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'threshold', - type: 'uint256', - }, - ], - name: 'InsufficientSignatures', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'recipients', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'accountIds', - type: 'uint256', - }, - ], - name: 'InvalidArrayLength', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'InvalidOwner', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - ], - name: 'InvalidRecipient', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'ownerCount', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'threshold', - type: 'uint256', - }, - ], - name: 'InvalidRequirement', - type: 'error', - }, - { - inputs: [], - name: 'InvalidShortString', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'InvalidSignature', - type: 'error', - }, - { - inputs: [], - name: 'ReentrancyGuardReentrantCall', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'ownerCount', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'threshold', - type: 'uint256', - }, - ], - name: 'SetupFail', - type: 'error', - }, - { - inputs: [ - { - internalType: 'string', - name: 'str', - type: 'string', - }, - ], - name: 'StringTooLong', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'UnauthorizedAccount', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'deposit', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'token', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'tokenAmount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'ethAmount', - type: 'uint256', - }, - ], - name: 'Claim', - type: 'event', - }, - { - anonymous: false, - inputs: [], - name: 'EIP712DomainChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'digest', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'id', - type: 'bytes32', - }, - ], - name: 'ExecuteSuccess', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'ownerCount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'threshold', - type: 'uint256', - }, - ], - name: 'SetConfig', - type: 'event', - }, - { - inputs: [], - name: 'MAX_OWNER_COUNT', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'hash', - type: 'bytes32', - }, - { - internalType: 'bytes', - name: 'signatures', - type: 'bytes', - }, - ], - name: 'checkSignatures', - outputs: [], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'erc20', - type: 'address', - }, - { - internalType: 'bytes32[]', - name: 'accountIds', - type: 'bytes32[]', - }, - ], - name: 'claim', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'erc20', - type: 'address', - }, - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'bytes32[]', - name: 'accountIds', - type: 'bytes32[]', - }, - ], - name: 'claimTo', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'eip712Domain', - outputs: [ - { - internalType: 'bytes1', - name: 'fields', - type: 'bytes1', - }, - { - internalType: 'string', - name: 'name', - type: 'string', - }, - { - internalType: 'string', - name: 'version', - type: 'string', - }, - { - internalType: 'uint256', - name: 'chainId', - type: 'uint256', - }, - { - internalType: 'address', - name: 'verifyingContract', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'salt', - type: 'bytes32', - }, - { - internalType: 'uint256[]', - name: 'extensions', - type: 'uint256[]', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - components: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - internalType: 'struct MultiSigWallet.Call[]', - name: 'calls', - type: 'tuple[]', - }, - { - internalType: 'bytes', - name: 'signatures', - type: 'bytes', - }, - { - internalType: 'bytes32', - name: 'id', - type: 'bytes32', - }, - ], - internalType: 'struct MultiSigWallet.Operation[]', - name: 'operations', - type: 'tuple[]', - }, - ], - name: 'execute', - outputs: [ - { - internalType: 'bytes[][]', - name: 'results', - type: 'bytes[][]', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'accountId', - type: 'bytes32', - }, - ], - name: 'getAccount', - outputs: [ - { - internalType: 'bytes', - name: 'bytecode', - type: 'bytes', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32[]', - name: 'accountIds', - type: 'bytes32[]', - }, - ], - name: 'getAccounts', - outputs: [ - { - internalType: 'bytes32[]', - name: '', - type: 'bytes32[]', - }, - { - internalType: 'address[]', - name: 'accounts', - type: 'address[]', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'isOwner', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'hash', - type: 'bytes32', - }, - { - internalType: 'bytes', - name: 'signatures', - type: 'bytes', - }, - ], - name: 'isValidSignature', - outputs: [ - { - internalType: 'bytes4', - name: 'magicValue', - type: 'bytes4', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'nonce', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'owners', - outputs: [ - { - internalType: 'address[]', - name: '', - type: 'address[]', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'recipient', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address[]', - name: 'owners_', - type: 'address[]', - }, - { - internalType: 'uint256', - name: 'threshold_', - type: 'uint256', - }, - ], - name: 'setConfig', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address[]', - name: 'owners_', - type: 'address[]', - }, - { - internalType: 'uint256', - name: 'threshold_', - type: 'uint256', - }, - ], - name: 'setup', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'threshold', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'token', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'version', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - stateMutability: 'payable', - type: 'receive', - }, -] as const satisfies Abi; - -export type MultiSigWalletAbi = typeof MULTI_SIG_WALLET_ABI; diff --git a/src/api/defi-client.ts b/src/api/defi-client.ts index 4f8d541..3527230 100644 --- a/src/api/defi-client.ts +++ b/src/api/defi-client.ts @@ -1,3 +1,4 @@ +import type { Address, Hex } from 'viem'; import type { AccountsControllerGetAssetBalancesV1BaseCurrencyEnum, AccountsControllerGetAssetBalancesV1SortByEnum, @@ -30,10 +31,16 @@ import { InvoicesApi, PayoutsApi, QueueOperationsApi, + ResponseError, + SmartContractVersionsApi, TransactionsApi, } from '../../generated-contracts'; +import { type AbiCacheEntry, AbiProvider } from '../abi-provider'; +import { TRON_CHAIN_IDS } from '../blockchain/tron-chains'; +import { formatCreditsWarning, parseCreditsError } from '../errors'; +import { packSignatures } from '../utils/transactions/signatures'; +import { TRON_ADDRESS_PREFIX, tronToEvmHex } from '../utils/tron-validation'; import type { - Account, AccountDeployment, AccountDetails, AssetBalanceList, @@ -64,7 +71,6 @@ import type { TransactionStatus, } from './models'; import { - mapAccount, mapAccountDetails, mapAssetBalanceList, mapBalanceSummary, @@ -90,6 +96,7 @@ export interface DefiClientOptions { defaultHeaders?: HTTPHeaders; credentials?: RequestCredentials; queryParamsStringify?: (params: Record) => string; + abiCacheDir?: string; } type ChainIdentifier = number | string; @@ -114,18 +121,21 @@ export interface CreatePayoutParams extends ChainScopedParams { recipient: string; trackingId?: string; callbackUrl?: string; - nonce?: number; + nonce?: string; } export interface GetDeploymentQueueParams extends ChainScopedParams { - statuses?: Array<'PENDING' | 'READY' | 'EXECUTING' | 'EXECUTED' | 'FAILED'>; + statuses?: Array<'PENDING' | 'READY' | 'EXECUTED' | 'FAILED' | 'CANCELLED'>; page?: number; pageSize?: number; } export interface SubmitOperationSignatureParams extends ChainScopedParams { operationId: string; + /** Raw ECDSA signature (hex). Will be packed automatically based on contract version. */ signature: string; + /** Signer address. Required for v1.1.0+ contracts to pack the signature. */ + signerAddress: string; } export interface ExecuteOperationParams extends ChainScopedParams { @@ -273,7 +283,13 @@ export class DefiClient { private readonly payoutsApi: PayoutsApi; private readonly queueOperationsApi: QueueOperationsApi; private readonly transactionsApi: TransactionsApi; - private defaultAccountId?: string; + private readonly smartContractVersionsApi: SmartContractVersionsApi; + private readonly abiProvider: AbiProvider; + private accountInfoPromise?: Promise<{ + accountId: string; + smartContractVersionId: string; + details: AccountDetails; + }>; private selectedDeployment?: AccountDeployment; private selectedChainId?: string; @@ -306,44 +322,38 @@ export class DefiClient { this.payoutsApi = new PayoutsApi(this.config); this.queueOperationsApi = new QueueOperationsApi(this.config); this.transactionsApi = new TransactionsApi(this.config); + this.smartContractVersionsApi = new SmartContractVersionsApi(this.config); + this.abiProvider = new AbiProvider(this.smartContractVersionsApi, options.abiCacheDir); + } + + async getContractAbi(versionId?: string): Promise { + const resolvedVersionId = versionId ?? (await this.resolveSmartContractVersionId()); + return this.abiProvider.getAbi(resolvedVersionId); } async getAssetBalances(params: GetAssetBalancesParams): Promise { const accountId = await this.resolveAccountId(); const chainId = params.chainId ?? (await this.resolveDeployment()).chainId; - const response = await this.accountsApi.accountsControllerGetAssetBalancesV1({ - accountId, - baseCurrency: params.baseCurrency as AccountsControllerGetAssetBalancesV1BaseCurrencyEnum, - chainId: chainId.toString(), - sortBy: params.sortBy as AccountsControllerGetAssetBalancesV1SortByEnum | undefined, - sortOrder: params.sortOrder as AccountsControllerGetAssetBalancesV1SortOrderEnum | undefined, - currencyIds: params.currencyIds, - page: params.page, - pageSize: params.pageSize, - }); + const response = await this.callApi(() => + this.accountsApi.accountsControllerGetAssetBalancesV1({ + accountId, + baseCurrency: params.baseCurrency as AccountsControllerGetAssetBalancesV1BaseCurrencyEnum, + chainId: chainId.toString(), + sortBy: params.sortBy as AccountsControllerGetAssetBalancesV1SortByEnum | undefined, + sortOrder: params.sortOrder as AccountsControllerGetAssetBalancesV1SortOrderEnum | undefined, + currencyIds: params.currencyIds, + page: params.page, + pageSize: params.pageSize, + }), + ); return mapAssetBalanceList(response); } - async getAccounts(): Promise { - const accounts = await this.accountsApi.accountsControllerFindUserAccountsV1(); - const firstAccount = accounts[0]; - - if (!firstAccount) { - throw new Error('No accounts are linked to this API key.'); - } - - this.defaultAccountId = firstAccount.id; - return accounts.map(mapAccount); - } - async getAccount(): Promise { - const resolvedAccountId = await this.resolveAccountId(); - const accountDetails = await this.accountsApi.accountsControllerFindAccountByIdV1({ - accountId: resolvedAccountId, - }); - return mapAccountDetails(accountDetails); + const info = await this.resolveAccountInfo(); + return info.details; } async getDeployments(accountDetails?: AccountDetails): Promise { @@ -383,16 +393,18 @@ export class DefiClient { async getAccountBalanceSummary(params: GetAccountBalanceSummaryParams): Promise { const resolvedAccountId = await this.resolveAccountId(); - const summary = await this.accountsApi.accountsControllerGetBalanceSummaryV1({ - accountId: resolvedAccountId, - baseCurrency: params.baseCurrency as AccountsControllerGetBalanceSummaryV1BaseCurrencyEnum, - chainId: params.chainId.toString(), - }); + const summary = await this.callApi(() => + this.accountsApi.accountsControllerGetBalanceSummaryV1({ + accountId: resolvedAccountId, + baseCurrency: params.baseCurrency as AccountsControllerGetBalanceSummaryV1BaseCurrencyEnum, + chainId: params.chainId.toString(), + }), + ); return mapBalanceSummary(summary); } async getCurrencies(): Promise { - const currencies = await this.currenciesApi.currenciesControllerFindAllV1(); + const currencies = await this.callApi(() => this.currenciesApi.currenciesControllerFindAllV1()); return currencies.map(mapCurrency); } @@ -415,7 +427,16 @@ export class DefiClient { return true; } - return currency.chainId === targetChain; + if (currency.chainId !== targetChain) { + return false; + } + + // On TVM chains, exclude currencies with EVM-style addresses (0x...) — stale data + if (TRON_CHAIN_IDS.has(Number(targetChain)) && currency.address?.startsWith('0x')) { + return false; + } + + return true; }); if (matches.length === 0) { @@ -452,21 +473,23 @@ export class DefiClient { async getInvoices(params: GetInvoicesParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.invoicesApi.invoicesControllerFindInvoicesByDeploymentV1({ - deploymentId, - id: params.id, - createdFrom: params.createdFrom, - createdTo: params.createdTo, - updatedFrom: params.updatedFrom, - updatedTo: params.updatedTo, - currencyIds: params.currencyIds, - statuses: params.statuses as InvoicesControllerFindInvoicesByDeploymentV1StatusesEnum[] | undefined, - trackingId: params.trackingId, - sortBy: params.sortBy as InvoicesControllerFindInvoicesByDeploymentV1SortByEnum | undefined, - sortOrder: params.sortOrder as InvoicesControllerFindInvoicesByDeploymentV1SortOrderEnum | undefined, - page: params.page, - pageSize: params.pageSize, - }); + const response = await this.callApi(() => + this.invoicesApi.invoicesControllerFindInvoicesByDeploymentV1({ + deploymentId, + id: params.id, + createdFrom: params.createdFrom, + createdTo: params.createdTo, + updatedFrom: params.updatedFrom, + updatedTo: params.updatedTo, + currencyIds: params.currencyIds, + statuses: params.statuses as InvoicesControllerFindInvoicesByDeploymentV1StatusesEnum[] | undefined, + trackingId: params.trackingId, + sortBy: params.sortBy as InvoicesControllerFindInvoicesByDeploymentV1SortByEnum | undefined, + sortOrder: params.sortOrder as InvoicesControllerFindInvoicesByDeploymentV1SortOrderEnum | undefined, + page: params.page, + pageSize: params.pageSize, + }), + ); return mapInvoiceList(response); } @@ -474,10 +497,12 @@ export class DefiClient { async getInvoice(params: GetInvoiceParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.invoicesApi.invoicesControllerFindInvoiceByIdV1({ - deploymentId, - invoiceId: params.invoiceId, - }); + const response = await this.callApi(() => + this.invoicesApi.invoicesControllerFindInvoiceByIdV1({ + deploymentId, + invoiceId: params.invoiceId, + }), + ); return mapInvoiceDetails(response); } @@ -485,17 +510,19 @@ export class DefiClient { async createInvoice(params: CreateInvoiceParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.invoicesApi.invoicesControllerCreateInvoiceV1({ - deploymentId, - createInvoiceDto: { - requestedAmount: params.requestedAmount ?? null, - trackingId: params.trackingId ?? null, - callbackUrl: params.callbackUrl ?? null, - paymentPageButtonUrl: params.paymentPageButtonUrl ?? null, - paymentPageButtonText: params.paymentPageButtonText ?? null, - currencyIds: params.currencyIds, - }, - }); + const response = await this.callApi(() => + this.invoicesApi.invoicesControllerCreateInvoiceV1({ + deploymentId, + createInvoiceDto: { + requestedAmount: params.requestedAmount ?? null, + trackingId: params.trackingId ?? null, + callbackUrl: params.callbackUrl ?? null, + paymentPageButtonUrl: params.paymentPageButtonUrl ?? null, + paymentPageButtonText: params.paymentPageButtonText ?? null, + currencyIds: params.currencyIds, + }, + }), + ); return mapInvoice(response); } @@ -504,11 +531,13 @@ export class DefiClient { const deploymentId = await this.resolveDeploymentId(params.chainId); const payload = this.buildInvoiceUpdatePayload(params); - const response = await this.invoicesApi.invoicesControllerUpdateInvoiceV1({ - deploymentId, - invoiceId: params.invoiceId, - updateInvoiceDto: payload, - }); + const response = await this.callApi(() => + this.invoicesApi.invoicesControllerUpdateInvoiceV1({ + deploymentId, + invoiceId: params.invoiceId, + updateInvoiceDto: payload, + }), + ); return mapInvoice(response); } @@ -516,18 +545,20 @@ export class DefiClient { async createPayout(params: CreatePayoutParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.payoutsApi.payoutsControllerCreateV1({ - deploymentId, - createPayoutDto: { + const response = await this.callApi(() => + this.payoutsApi.payoutsControllerCreateV1({ deploymentId, - currencyId: params.currencyId, - amount: params.amount, - toAddress: params.recipient, - trackingId: params.trackingId, - callbackUrl: params.callbackUrl, - nonce: params.nonce?.toString(), - }, - }); + createPayoutDto: { + deploymentId, + currencyId: params.currencyId, + amount: params.amount, + toAddress: params.recipient, + trackingId: params.trackingId, + callbackUrl: params.callbackUrl, + nonce: params.nonce, + }, + }), + ); return mapPayout(response); } @@ -535,23 +566,25 @@ export class DefiClient { async getPayouts(params: GetPayoutsParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.payoutsApi.payoutsControllerFindAllV1({ - deploymentId, - id: params.id, - createdFrom: params.createdFrom, - createdTo: params.createdTo, - updatedFrom: params.updatedFrom, - updatedTo: params.updatedTo, - currencyIds: params.currencyIds, - statuses: params.statuses as PayoutsControllerFindAllV1StatusesEnum[] | undefined, - trackingId: params.trackingId, - createdBy: params.createdBy, - toAddress: params.toAddress, - sortBy: params.sortBy as PayoutsControllerFindAllV1SortByEnum | undefined, - sortOrder: params.sortOrder as PayoutsControllerFindAllV1SortOrderEnum | undefined, - page: params.page, - pageSize: params.pageSize, - }); + const response = await this.callApi(() => + this.payoutsApi.payoutsControllerFindAllV1({ + deploymentId, + id: params.id, + createdFrom: params.createdFrom, + createdTo: params.createdTo, + updatedFrom: params.updatedFrom, + updatedTo: params.updatedTo, + currencyIds: params.currencyIds, + statuses: params.statuses as PayoutsControllerFindAllV1StatusesEnum[] | undefined, + trackingId: params.trackingId, + createdBy: params.createdBy, + toAddress: params.toAddress, + sortBy: params.sortBy as PayoutsControllerFindAllV1SortByEnum | undefined, + sortOrder: params.sortOrder as PayoutsControllerFindAllV1SortOrderEnum | undefined, + page: params.page, + pageSize: params.pageSize, + }), + ); return mapPayoutList(response); } @@ -559,10 +592,12 @@ export class DefiClient { async getPayout(params: GetPayoutParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.payoutsApi.payoutsControllerFindOneV1({ - deploymentId, - payoutId: params.payoutId, - }); + const response = await this.callApi(() => + this.payoutsApi.payoutsControllerFindOneV1({ + deploymentId, + payoutId: params.payoutId, + }), + ); return mapPayoutDetail(response); } @@ -571,11 +606,13 @@ export class DefiClient { const deploymentId = await this.resolveDeploymentId(params.chainId); const payload = this.buildPayoutUpdatePayload(params); - const response = await this.payoutsApi.payoutsControllerUpdateV1({ - deploymentId, - payoutId: params.payoutId, - updatePayoutDto: payload, - }); + const response = await this.callApi(() => + this.payoutsApi.payoutsControllerUpdateV1({ + deploymentId, + payoutId: params.payoutId, + updatePayoutDto: payload, + }), + ); return mapPayout(response); } @@ -583,12 +620,14 @@ export class DefiClient { async getDeploymentQueue(params: GetDeploymentQueueParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.queueOperationsApi.queueOperationsControllerGetDeploymentQueueV1({ - deploymentId, - page: params.page, - pageSize: params.pageSize, - statuses: params.statuses, - }); + const response = await this.callApi(() => + this.queueOperationsApi.queueOperationsControllerGetDeploymentQueueV1({ + deploymentId, + page: params.page, + pageSize: params.pageSize, + statuses: params.statuses, + }), + ); return mapDeploymentQueue(response); } @@ -596,24 +635,28 @@ export class DefiClient { async getTransactions(params: GetTransactionsParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.transactionsApi.transactionsControllerGetTransactionsV1({ - deploymentId, - id: params.id, - operationId: params.operationId, - operationTypes: params.operationTypes as TransactionsControllerGetTransactionsV1OperationTypesEnum[] | undefined, - statuses: params.statuses as TransactionsControllerGetTransactionsV1StatusesEnum[] | undefined, - txHash: params.txHash, - currencyIds: params.currencyIds, - createdFrom: params.createdFrom, - createdTo: params.createdTo, - updatedFrom: params.updatedFrom, - updatedTo: params.updatedTo, - isClaimed: params.isClaimed, - sortBy: params.sortBy as TransactionsControllerGetTransactionsV1SortByEnum | undefined, - sortOrder: params.sortOrder as TransactionsControllerGetTransactionsV1SortOrderEnum | undefined, - page: params.page, - pageSize: params.pageSize, - }); + const response = await this.callApi(() => + this.transactionsApi.transactionsControllerGetTransactionsV1({ + deploymentId, + id: params.id, + operationId: params.operationId, + operationTypes: params.operationTypes as + | TransactionsControllerGetTransactionsV1OperationTypesEnum[] + | undefined, + statuses: params.statuses as TransactionsControllerGetTransactionsV1StatusesEnum[] | undefined, + txHash: params.txHash, + currencyIds: params.currencyIds, + createdFrom: params.createdFrom, + createdTo: params.createdTo, + updatedFrom: params.updatedFrom, + updatedTo: params.updatedTo, + isClaimed: params.isClaimed, + sortBy: params.sortBy as TransactionsControllerGetTransactionsV1SortByEnum | undefined, + sortOrder: params.sortOrder as TransactionsControllerGetTransactionsV1SortOrderEnum | undefined, + page: params.page, + pageSize: params.pageSize, + }), + ); return mapTransactionList(response); } @@ -621,24 +664,39 @@ export class DefiClient { async getTransaction(params: GetTransactionParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.transactionsApi.transactionsControllerGetTransactionDetailsV1({ - deploymentId, - transactionId: params.transactionId, - }); + const response = await this.callApi(() => + this.transactionsApi.transactionsControllerGetTransactionDetailsV1({ + deploymentId, + transactionId: params.transactionId, + }), + ); return mapTransactionDetails(response); } async submitOperationSignature(params: SubmitOperationSignatureParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); + const contractAbi = await this.getContractAbi(); - const response = await this.queueOperationsApi.queueOperationsControllerSubmitSignatureV1({ - deploymentId, - operationId: params.operationId, - submitSignatureDto: { - signature: params.signature, - }, - }); + // Normalize Tron base58 addresses to 0x hex for signature packing + const signerAddress = params.signerAddress.startsWith(TRON_ADDRESS_PREFIX) + ? (tronToEvmHex(params.signerAddress) as Address) + : (params.signerAddress as Address); + + const packedSignature = packSignatures( + [{ user: signerAddress, sign: params.signature as Hex }], + contractAbi.version, + ); + + const response = await this.callApi(() => + this.queueOperationsApi.queueOperationsControllerSubmitSignatureV1({ + deploymentId, + operationId: params.operationId, + submitSignatureDto: { + signature: packedSignature, + }, + }), + ); return mapSignature(response); } @@ -646,19 +704,21 @@ export class DefiClient { async getClaims(params: GetClaimsParams): Promise { const deploymentId = await this.resolveDeploymentId(params.chainId); - const response = await this.claimsApi.claimsControllerGetClaimsV1({ - deploymentId, - createdFrom: params.createdFrom, - createdTo: params.createdTo, - updatedFrom: params.updatedFrom, - updatedTo: params.updatedTo, - currencyIds: params.currencyIds, - invoiceId: params.invoiceId, - sortBy: params.sortBy as ClaimsControllerGetClaimsV1SortByEnum | undefined, - sortOrder: params.sortOrder as ClaimsControllerGetClaimsV1SortOrderEnum | undefined, - page: params.page, - pageSize: params.pageSize, - }); + const response = await this.callApi(() => + this.claimsApi.claimsControllerGetClaimsV1({ + deploymentId, + createdFrom: params.createdFrom, + createdTo: params.createdTo, + updatedFrom: params.updatedFrom, + updatedTo: params.updatedTo, + currencyIds: params.currencyIds, + invoiceId: params.invoiceId, + sortBy: params.sortBy as ClaimsControllerGetClaimsV1SortByEnum | undefined, + sortOrder: params.sortOrder as ClaimsControllerGetClaimsV1SortOrderEnum | undefined, + page: params.page, + pageSize: params.pageSize, + }), + ); return mapClaimsResponse(response); } @@ -666,9 +726,11 @@ export class DefiClient { async getClaimableCurrencies(chainId?: ChainIdentifier): Promise { const deploymentId = await this.resolveDeploymentId(chainId); - const response = await this.claimsApi.claimsControllerGetClaimableCurrenciesV1({ - deploymentId, - }); + const response = await this.callApi(() => + this.claimsApi.claimsControllerGetClaimableCurrenciesV1({ + deploymentId, + }), + ); return response.map(mapCurrency); } @@ -740,20 +802,51 @@ export class DefiClient { return payload as UpdatePayoutDto; } - private async resolveAccountId(): Promise { - if (this.defaultAccountId) { - return this.defaultAccountId; + private resolveAccountInfo(): Promise<{ + accountId: string; + smartContractVersionId: string; + details: AccountDetails; + }> { + if (!this.accountInfoPromise) { + this.accountInfoPromise = this.fetchAccountInfo(); } + return this.accountInfoPromise; + } - const accounts = await this.getAccounts(); + private async fetchAccountInfo(): Promise<{ + accountId: string; + smartContractVersionId: string; + details: AccountDetails; + }> { + const accounts = await this.callApi(() => this.accountsApi.accountsControllerFindUserAccountsV1()); const firstAccount = accounts[0]; if (!firstAccount) { throw new Error('No accounts are linked to this API key.'); } - this.defaultAccountId = firstAccount.id; - return firstAccount.id; + const raw = await this.callApi(() => + this.accountsApi.accountsControllerFindAccountByIdV1({ + accountId: firstAccount.id, + }), + ); + const details = mapAccountDetails(raw); + + return { + accountId: firstAccount.id, + smartContractVersionId: raw.account.smartContractVersionId, + details, + }; + } + + private async resolveAccountId(): Promise { + const info = await this.resolveAccountInfo(); + return info.accountId; + } + + private async resolveSmartContractVersionId(): Promise { + const info = await this.resolveAccountInfo(); + return info.smartContractVersionId; } private async resolveDeployment(chainId?: ChainIdentifier): Promise { @@ -776,4 +869,19 @@ export class DefiClient { private normalizeChainId(chainId: ChainIdentifier): string { return typeof chainId === 'number' ? chainId.toString() : chainId; } + + private async callApi(fn: () => Promise): Promise { + try { + return await fn(); + } catch (err) { + if (err instanceof ResponseError) { + const creditsError = await parseCreditsError(err); + if (creditsError) { + console.warn(formatCreditsWarning(creditsError.required, creditsError.available)); + throw creditsError; + } + } + throw err; + } + } } diff --git a/src/api/index.ts b/src/api/index.ts index 2b12426..0d46feb 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -49,7 +49,6 @@ export type { TransactionDetails, TransactionInvoice, TransactionList, - User, } from './models'; export { AssetSortField, diff --git a/src/api/models/mappers.ts b/src/api/models/mappers.ts index b7f6f93..4f43af3 100644 --- a/src/api/models/mappers.ts +++ b/src/api/models/mappers.ts @@ -23,7 +23,6 @@ import type { TransactionInvoiceResponseDto, TransactionListResponseDto, TransactionResponseDto, - UserResponseDto, } from '../../../generated-contracts'; import type { Account, @@ -59,13 +58,10 @@ import type { TransactionList, TransactionOperationType, TransactionStatus, - User, } from './types'; const clone = (value: T): T => ({ ...value }); -export const mapUser = (dto: UserResponseDto): User => clone(dto); - export const mapAccount = (dto: AccountResponseDto): Account => clone(dto); export const mapAccountDeployment = (dto: AccountDeploymentDto): AccountDeployment => ({ diff --git a/src/api/models/types.ts b/src/api/models/types.ts index f862032..4dc963f 100644 --- a/src/api/models/types.ts +++ b/src/api/models/types.ts @@ -20,7 +20,6 @@ import type { TransactionInvoiceResponseDto, TransactionListResponseDto, TransactionResponseDto, - UserResponseDto, } from '../../../generated-contracts'; export enum FiatCurrency { @@ -29,7 +28,6 @@ export enum FiatCurrency { Cny = 'cny', } -export type User = UserResponseDto; export type Account = AccountResponseDto; export interface AccountDetails { @@ -136,12 +134,12 @@ export enum QueueOperationType { MultisigConfigChange = 'MULTISIG_CONFIG_CHANGE', Reject = 'REJECT', Payout = 'PAYOUT', + DappTransaction = 'DAPP_TRANSACTION', } export enum QueueOperationStatus { Pending = 'PENDING', Ready = 'READY', - Executing = 'EXECUTING', Executed = 'EXECUTED', Failed = 'FAILED', Cancelled = 'CANCELLED', @@ -162,6 +160,7 @@ export interface ExecuteBatchOperationsResult { success: boolean; } +/** @deprecated Use `operationType` to determine transaction direction instead. */ export enum TransactionDirection { In = 'IN', Out = 'OUT', @@ -195,6 +194,7 @@ export type Transaction = Omit< TransactionResponseDto, 'direction' | 'status' | 'operationType' | 'currency' | 'invoice' > & { + /** @deprecated Use `operationType` to determine transaction direction instead. */ direction: TransactionDirection; status: TransactionStatus; operationType: TransactionOperationType; diff --git a/src/blockchain/get-chain.ts b/src/blockchain/get-chain.ts index c8226ce..f955111 100644 --- a/src/blockchain/get-chain.ts +++ b/src/blockchain/get-chain.ts @@ -1,10 +1,15 @@ import type { Chain } from 'viem'; import * as viemChains from 'viem/chains'; +import { getTronChainById, TRON_CHAIN_IDS, type TronChainConfig } from './tron-chains'; -export function getChainById(chainId: string, rpcUrl?: string): Chain { +/** + * Resolves an EVM chain by ID. Returns a viem `Chain` type. + * Throws if the chain ID is not a known EVM chain. + */ +export function getEvmChainById(chainId: string, rpcUrl?: string): Chain { const chain = Object.values(viemChains).find((item) => item.id.toString() === chainId); if (!chain) { - throw new Error(`Unsupported chain ID: ${chainId}. Specified chain is not preconfigured in viem.`); + throw new Error(`Unsupported EVM chain ID: ${chainId}. Specified chain is not preconfigured in viem.`); } if (!rpcUrl) { @@ -19,3 +24,30 @@ export function getChainById(chainId: string, rpcUrl?: string): Chain { }, } as Chain; } + +/** + * Resolves a Tron (TVM) chain by ID. Returns a `TronChainConfig` type. + * Throws if the chain ID is not a known Tron chain. + * Re-export of `getTronChainById` with a consistent naming convention. + */ +export const getTvmChainById = getTronChainById; + +/** + * Universal chain resolver — tries EVM first, then Tron. + * Returns `Chain | TronChainConfig`. Use `getEvmChainById` or `getTvmChainById` + * when you need a narrowed return type. + */ +export function getChainById(chainId: string, rpcUrl?: string): Chain | TronChainConfig { + const evmChain = Object.values(viemChains).find((item) => item.id.toString() === chainId); + + if (evmChain) { + return getEvmChainById(chainId, rpcUrl); + } + + const numericId = Number(chainId); + if (TRON_CHAIN_IDS.has(numericId)) { + return getTronChainById(chainId, rpcUrl); + } + + throw new Error(`Unsupported chain ID: ${chainId}. Not a known EVM or Tron chain.`); +} diff --git a/src/blockchain/index.ts b/src/blockchain/index.ts index 5939642..6e69338 100644 --- a/src/blockchain/index.ts +++ b/src/blockchain/index.ts @@ -1,6 +1,13 @@ +export { getChainById, getEvmChainById, getTvmChainById } from './get-chain'; export type { CreateExecuteTypedDataArgs, MultisigBlockchainClientOptions, SignExecuteTypedDataArgs, } from './multisig-client'; export { MultisigBlockchainClient } from './multisig-client'; +export { getTronChainById, isTronChain, TRON_CHAIN_IDS, type TronChainConfig } from './tron-chains'; +export { + TronMultisigBlockchainClient, + type TronMultisigBlockchainClientOptions, + type TronPreparedTransaction, +} from './tron-multisig-client'; diff --git a/src/blockchain/multisig-client.ts b/src/blockchain/multisig-client.ts index 249602c..fcd3814 100644 --- a/src/blockchain/multisig-client.ts +++ b/src/blockchain/multisig-client.ts @@ -1,9 +1,9 @@ -import type { Account, Address, Hex, PublicClient, TypedDataDomain } from 'viem'; +import type { Abi, Account, Address, Hex, PublicClient, TypedDataDomain } from 'viem'; import { encodeFunctionData } from 'viem'; -import type { CallDto, QueueOperationResponseDto } from '../../generated-contracts'; -import { MULTI_SIG_WALLET_ABI } from '../abi'; +import type { QueueOperationResponseDto } from '../../generated-contracts'; +import type { AbiCacheEntry } from '../abi-provider'; import type { PreparedTransaction } from '../utils/transactions/builders'; -import { buildExecuteOperationsTransaction } from '../utils/transactions/builders'; +import { buildExecuteOperationsTransaction, ensureHexPrefix, normalizeCalls } from '../utils/transactions/builders'; import type { ExecuteTypedDataPayload } from '../utils/transactions/eip712'; import { buildExecuteTypedData, @@ -14,6 +14,7 @@ import { export interface MultisigBlockchainClientOptions { chainId: string; publicClient: PublicClient; + contractAbi: AbiCacheEntry; } export interface CreateExecuteTypedDataArgs { @@ -32,17 +33,18 @@ export interface SignExecuteTypedDataArgs { export class MultisigBlockchainClient { private readonly publicClientInstance: PublicClient; private readonly chainIdNumber: number; + private readonly abi: Abi; constructor(options: MultisigBlockchainClientOptions) { this.chainIdNumber = Number(options.chainId); - this.publicClientInstance = options.publicClient; + this.abi = options.contractAbi.abi; } async createExecuteTypedData(args: CreateExecuteTypedDataArgs): Promise { if (args.domainOverride) { const message = buildExecuteTypedMessage({ - calls: this.normalizeCalls(args.operation.calls), + calls: normalizeCalls(args.operation.calls), nonce: args.operation.nonce, }); @@ -53,6 +55,7 @@ export class MultisigBlockchainClient { contractAddress: args.contractAddress, operation: args.operation, publicClient: this.publicClientInstance, + abi: this.abi, }); } @@ -64,23 +67,16 @@ export class MultisigBlockchainClient { contractAddress: params.contractAddress as Address, chainId: this.chainIdNumber, operations: params.operations, + abi: this.abi, }); } buildClaimCalldata(params: { erc20: Address; depositAccountIds: Array; to?: Address }): Hex { - const depositIds = params.depositAccountIds.map((id) => `0x${id.replace(/^0x/, '')}` as `0x${string}`); + const depositIds = params.depositAccountIds.map(ensureHexPrefix); return encodeFunctionData({ - abi: MULTI_SIG_WALLET_ABI, + abi: this.abi, functionName: params.to ? 'claimTo' : 'claim', args: params.to ? [params.erc20, params.to, depositIds] : [params.erc20, depositIds], }); } - - private normalizeCalls(calls: CallDto[]): Array<{ to: string; value: string | number | bigint; data: string }> { - return calls.map((call) => ({ - to: call.to, - value: call.value ?? '0', - data: call.data ?? '0x', - })); - } } diff --git a/src/blockchain/tron-chains.spec.ts b/src/blockchain/tron-chains.spec.ts new file mode 100644 index 0000000..5a7ceaf --- /dev/null +++ b/src/blockchain/tron-chains.spec.ts @@ -0,0 +1,68 @@ +import { getTronChainById, isTronChain, TRON_CHAIN_IDS } from './tron-chains'; + +describe('getTronChainById', () => { + describe('known chain IDs', () => { + it('resolves Tron Mainnet (728126428)', () => { + const chain = getTronChainById('728126428'); + expect(chain.id).toBe(728126428); + expect(chain.name).toBe('Tron Mainnet'); + expect(chain.network).toBe('mainnet'); + expect(chain.rpcUrls.default.http.length).toBeGreaterThan(0); + }); + + it('resolves Shasta Testnet (2494104990)', () => { + const chain = getTronChainById('2494104990'); + expect(chain.id).toBe(2494104990); + expect(chain.name).toBe('Tron Shasta Testnet'); + expect(chain.network).toBe('shasta'); + }); + }); + + describe('custom RPC override', () => { + it('uses custom RPC URL when provided', () => { + const customRpc = 'https://custom-tron-node.example.com'; + const chain = getTronChainById('728126428', customRpc); + expect(chain.rpcUrls.default.http).toEqual([customRpc]); + }); + + it('uses default RPC when no custom URL provided', () => { + const chain = getTronChainById('728126428'); + expect(chain.rpcUrls.default.http[0]).toContain('trongrid'); + }); + }); + + describe('unknown chain ID', () => { + it('throws for unknown chain ID', () => { + expect(() => getTronChainById('999999')).toThrow('Unsupported Tron chain ID'); + }); + }); +}); + +describe('TRON_CHAIN_IDS', () => { + it('contains known Tron chain IDs', () => { + expect(TRON_CHAIN_IDS.has(728126428)).toBe(true); + expect(TRON_CHAIN_IDS.has(2494104990)).toBe(true); + }); + + it('does not contain EVM chain IDs', () => { + expect(TRON_CHAIN_IDS.has(1)).toBe(false); + expect(TRON_CHAIN_IDS.has(137)).toBe(false); + }); +}); + +describe('isTronChain', () => { + it('returns true for TronChainConfig', () => { + const chain = getTronChainById('728126428'); + expect(isTronChain(chain)).toBe(true); + }); + + it('returns false for viem Chain-like object', () => { + const evmChain = { + id: 1, + name: 'Ethereum', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: { default: { http: [] } }, + }; + expect(isTronChain(evmChain as never)).toBe(false); + }); +}); diff --git a/src/blockchain/tron-chains.ts b/src/blockchain/tron-chains.ts new file mode 100644 index 0000000..5edcf11 --- /dev/null +++ b/src/blockchain/tron-chains.ts @@ -0,0 +1,55 @@ +export interface TronChainConfig { + readonly id: number; + readonly name: string; + readonly network: string; + readonly rpcUrls: { + readonly default: { readonly http: readonly string[] }; + }; +} + +const TRON_CHAINS: ReadonlyMap = new Map([ + [ + 728126428, + { + id: 728126428, + name: 'Tron Mainnet', + network: 'mainnet', + rpcUrls: { default: { http: ['https://api.trongrid.io'] } }, + }, + ], + [ + 2494104990, + { + id: 2494104990, + name: 'Tron Shasta Testnet', + network: 'shasta', + rpcUrls: { default: { http: ['https://api.shasta.trongrid.io'] } }, + }, + ], +]); + +export const TRON_CHAIN_IDS: ReadonlySet = new Set(TRON_CHAINS.keys()); + +export function getTronChainById(chainId: string, rpcUrl?: string): TronChainConfig { + const id = Number(chainId); + const chain = TRON_CHAINS.get(id); + + if (!chain) { + throw new Error(`Unsupported Tron chain ID: ${chainId}. Known Tron chains: ${[...TRON_CHAIN_IDS].join(', ')}`); + } + + if (!rpcUrl) { + return chain; + } + + return { + ...chain, + rpcUrls: { default: { http: [rpcUrl] } }, + }; +} + +export function isTronChain(chain: unknown): chain is TronChainConfig { + if (typeof chain !== 'object' || chain === null) return false; + const candidate = chain as Record; + return typeof candidate.id === 'number' && TRON_CHAIN_IDS.has(candidate.id as number); +} diff --git a/src/blockchain/tron-multisig-client.spec.ts b/src/blockchain/tron-multisig-client.spec.ts new file mode 100644 index 0000000..526bd0c --- /dev/null +++ b/src/blockchain/tron-multisig-client.spec.ts @@ -0,0 +1,226 @@ +import type { AbiCacheEntry } from '../abi-provider'; +import type { TronAddress } from '../utils/tron-validation'; +import { TronMultisigBlockchainClient } from './tron-multisig-client'; + +const CONTRACT: TronAddress = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t' as TronAddress; +const CALLER: TronAddress = 'TRKAeHHtjKTfmKYVpt1K7vf4dHCrdNtAdv' as TronAddress; +const RECIPIENT: TronAddress = 'TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL' as TronAddress; +const TOKEN: TronAddress = 'TJCnKsPa7y5okkXvQAidZBzqx3QyQ6sxMW' as TronAddress; + +const MOCK_ABI = [ + { + inputs: [], + name: 'eip712Domain', + outputs: [ + { type: 'bytes1' }, + { type: 'string' }, + { type: 'string' }, + { type: 'uint256' }, + { type: 'address' }, + { type: 'bytes32' }, + { type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + type: 'tuple[]', + name: 'operations', + components: [ + { + type: 'tuple[]', + name: 'calls', + components: [ + { type: 'address', name: 'to' }, + { type: 'uint256', name: 'value' }, + { type: 'bytes', name: 'data' }, + ], + }, + { type: 'bytes', name: 'signatures' }, + { type: 'bytes32', name: 'id' }, + ], + }, + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { type: 'address', name: 'erc20' }, + { type: 'uint256[]', name: 'depositIds' }, + ], + name: 'claim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { type: 'address', name: 'erc20' }, + { type: 'address', name: 'to' }, + { type: 'uint256[]', name: 'depositIds' }, + ], + name: 'claimTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; + +const mockAbiEntry: AbiCacheEntry = { + abi: MOCK_ABI as unknown[], + version: '1.1.0', +} as AbiCacheEntry; + +describe('TronMultisigBlockchainClient', () => { + describe('constructor', () => { + it('creates client with valid options', () => { + const client = new TronMultisigBlockchainClient({ + chainId: '728126428', + tronWeb: {} as never, + contractAbi: mockAbiEntry, + defaultFeeLimit: 150_000_000, + }); + expect(client).toBeDefined(); + }); + + it('accepts unknown contract version without error', () => { + const unknownAbi: AbiCacheEntry = { abi: MOCK_ABI as unknown[], version: '9.9.9' } as AbiCacheEntry; + const client = new TronMultisigBlockchainClient({ + chainId: '728126428', + tronWeb: {} as never, + contractAbi: unknownAbi, + defaultFeeLimit: 150_000_000, + }); + + expect(client).toBeDefined(); + }); + }); + + describe('createExecuteTypedData', () => { + it('builds typed data with domain override (no RPC needed)', async () => { + const client = new TronMultisigBlockchainClient({ + chainId: '728126428', + tronWeb: {} as never, + contractAbi: mockAbiEntry, + defaultFeeLimit: 150_000_000, + }); + + const domain = { + name: 'MultiSigWallet', + version: '1.1.0', + chainId: 728126428n, + verifyingContract: CONTRACT, + }; + + const operation = { + calls: [{ to: RECIPIENT, value: '1000', data: '0x' }], + nonce: '1', + signatures: [], + executeOperationId: '0x01', + }; + + const result = await client.createExecuteTypedData({ + contractAddress: CONTRACT, + operation: operation as never, + domainOverride: domain, + }); + + expect(result.primaryType).toBe('Execute'); + expect(result.domain).toBe(domain); + expect(result.message.nonce).toBe(1n); + expect(result.message.calls).toHaveLength(1); + }); + }); + + describe('buildClaimTransaction', () => { + it('builds claim transaction with correct function name', async () => { + const mockTrigger = jest.fn().mockResolvedValue({ + transaction: { txID: 'abc123', raw_data: {} }, + }); + + const mockTronWeb = { + transactionBuilder: { + triggerSmartContract: mockTrigger, + }, + address: { + toHex: jest.fn().mockReturnValue(`41${'aa'.repeat(20)}`), + }, + }; + + const client = new TronMultisigBlockchainClient({ + chainId: '728126428', + tronWeb: mockTronWeb as never, + contractAbi: mockAbiEntry, + defaultFeeLimit: 150_000_000, + }); + + const result = await client.buildClaimTransaction({ + contractAddress: CONTRACT, + callerAddress: CALLER, + erc20: TOKEN, + depositIds: ['0x01', '0x02'], + }); + + expect(result).toBeDefined(); + expect(result.to).toBe(CONTRACT); + expect(result.chainId).toBe('728126428'); + expect(mockTrigger).toHaveBeenCalled(); + }); + + it('builds claimTo transaction when destination address provided', async () => { + const mockTrigger = jest.fn().mockResolvedValue({ + transaction: { txID: 'abc123', raw_data: {} }, + }); + + const mockTronWeb = { + transactionBuilder: { + triggerSmartContract: mockTrigger, + }, + address: { + toHex: jest.fn().mockReturnValue(`41${'aa'.repeat(20)}`), + }, + }; + + const client = new TronMultisigBlockchainClient({ + chainId: '728126428', + tronWeb: mockTronWeb as never, + contractAbi: mockAbiEntry, + defaultFeeLimit: 150_000_000, + }); + + const result = await client.buildClaimTransaction({ + contractAddress: CONTRACT, + callerAddress: CALLER, + erc20: TOKEN, + depositIds: ['0x01'], + to: RECIPIENT, + }); + + expect(result).toBeDefined(); + expect(result.to).toBe(CONTRACT); + }); + + it('throws when no deposit IDs provided', async () => { + const client = new TronMultisigBlockchainClient({ + chainId: '728126428', + tronWeb: {} as never, + contractAbi: mockAbiEntry, + defaultFeeLimit: 150_000_000, + }); + + await expect( + client.buildClaimTransaction({ + contractAddress: CONTRACT, + callerAddress: CALLER, + erc20: TOKEN, + depositIds: [], + }), + ).rejects.toThrow('No claimable deposits'); + }); + }); +}); diff --git a/src/blockchain/tron-multisig-client.ts b/src/blockchain/tron-multisig-client.ts new file mode 100644 index 0000000..b9a87ba --- /dev/null +++ b/src/blockchain/tron-multisig-client.ts @@ -0,0 +1,190 @@ +import type { TronWeb } from 'tronweb'; +import type { Abi } from 'viem'; +import { concatHex, encodeFunctionData, type Hex } from 'viem'; +import type { QueueOperationResponseDto } from '../../generated-contracts'; +import type { AbiCacheEntry } from '../abi-provider'; +import { ensureHexPrefix, normalizeCalls } from '../utils/transactions/builders'; +import { + buildTronExecuteTypedData, + fetchTronExecuteTypedDataDomain, + type TronExecuteTypedDataPayload, +} from '../utils/transactions/tron-tip712'; +import type { TronAddress } from '../utils/tron-types'; + +export interface TronMultisigBlockchainClientOptions { + chainId: string; + tronWeb: TronWeb; + contractAbi: AbiCacheEntry; + defaultFeeLimit: number; +} + +export interface TronPreparedTransaction { + readonly to: TronAddress; + readonly data: string; + readonly chainId: string; + readonly feeLimit: number; + readonly callValue: number; + readonly raw: unknown; +} + +export class TronMultisigBlockchainClient { + private readonly tronWebInstance: TronWeb; + private readonly chainId: string; + private readonly abi: Abi; + private readonly feeLimit: number; + private readonly executeFunctionSignature: string; + + constructor(options: TronMultisigBlockchainClientOptions) { + this.chainId = options.chainId; + this.tronWebInstance = options.tronWeb; + this.abi = options.contractAbi.abi as Abi; + this.feeLimit = options.defaultFeeLimit; + + const executeAbiItem = (this.abi as readonly { type: string; name?: string }[]).find( + (item) => item.type === 'function' && item.name === 'execute', + ); + if (!executeAbiItem) { + throw new Error('execute function not found in contract ABI'); + } + this.executeFunctionSignature = this.buildFunctionSignature(executeAbiItem); + } + + async createExecuteTypedData(args: { + contractAddress: TronAddress; + operation: QueueOperationResponseDto; + domainOverride?: TronExecuteTypedDataPayload['domain']; + }): Promise { + const calls = normalizeCalls(args.operation.calls); + + const domain = + args.domainOverride ?? + (await fetchTronExecuteTypedDataDomain({ + tronWeb: this.tronWebInstance, + contractAddress: args.contractAddress, + abi: this.abi, + })); + + return buildTronExecuteTypedData({ + domain, + calls: calls.map((call) => ({ + to: call.to as TronAddress, + value: typeof call.value === 'bigint' ? call.value : BigInt(call.value), + data: call.data, + })), + nonce: BigInt(args.operation.nonce), + }); + } + + async buildExecuteTransaction(params: { + contractAddress: TronAddress; + callerAddress: TronAddress; + operations: QueueOperationResponseDto[]; + feeLimit?: number; + }): Promise { + const feeLimit = params.feeLimit ?? this.feeLimit; + + const operations = params.operations.map((operation) => ({ + calls: operation.calls.map((call) => ({ + to: call.to, + value: call.value ? BigInt(call.value) : 0n, + data: call.data ?? '0x', + })), + signatures: concatHex(operation.signatures.map((sig) => sig.sign as Hex)), + id: operation.executeOperationId, + })); + + const data = encodeFunctionData({ + abi: this.abi, + functionName: 'execute', + args: [operations], + }); + + // Build transaction via TronWeb's triggerSmartContract with rawParameter. + // We pass the viem-encoded params (without selector) as rawParameter and derive + // the correct function selector from the ABI name to avoid double-encoding. + const rawParameter = data.slice(10); // ABI-encoded params without 0x + 4-byte selector + + const { transaction } = await this.tronWebInstance.transactionBuilder.triggerSmartContract( + params.contractAddress, + this.executeFunctionSignature, + { feeLimit, callValue: 0, rawParameter }, + [], + params.callerAddress, + ); + + return { + to: params.contractAddress, + data, + chainId: this.chainId, + feeLimit, + callValue: 0, + raw: transaction, + }; + } + + async buildClaimTransaction(params: { + contractAddress: TronAddress; + callerAddress: TronAddress; + erc20: TronAddress; + depositIds: string[]; + to?: TronAddress; + feeLimit?: number; + }): Promise { + if (params.depositIds.length === 0) { + throw new Error('No claimable deposits found for the specified parameters.'); + } + + const feeLimit = params.feeLimit ?? this.feeLimit; + const depositIds = params.depositIds.map(ensureHexPrefix); + + const args = params.to + ? [ + { type: 'address', value: params.erc20 }, + { type: 'address', value: params.to }, + { type: 'bytes32[]', value: depositIds }, + ] + : [ + { type: 'address', value: params.erc20 }, + { type: 'bytes32[]', value: depositIds }, + ]; + + const functionSignature = params.to ? 'claimTo(address,address,bytes32[])' : 'claim(address,bytes32[])'; + + const { transaction } = await this.tronWebInstance.transactionBuilder.triggerSmartContract( + params.contractAddress, + functionSignature, + { feeLimit, callValue: 0 }, + args, + params.callerAddress, + ); + + return { + to: params.contractAddress, + data: functionSignature, + chainId: this.chainId, + feeLimit, + callValue: 0, + raw: transaction, + }; + } + + /** + * Builds a Solidity function signature string from an ABI item. + * e.g. `execute((address,uint256,bytes)[],bytes,bytes32)[])` + * This is needed because TronWeb's triggerSmartContract computes the 4-byte + * function selector by keccak256-hashing this string. + */ + // biome-ignore lint/suspicious/noExplicitAny: ABI item structure is complex and varies + private buildFunctionSignature(abiItem: any): string { + const formatType = (input: { type: string; components?: unknown[] }): string => { + if (input.type === 'tuple' || input.type.startsWith('tuple')) { + const suffix = input.type.slice(5); // e.g. '[]' from 'tuple[]' + const inner = (input.components as { type: string; components?: unknown[] }[]).map(formatType).join(','); + return `(${inner})${suffix}`; + } + return input.type; + }; + const params = (abiItem.inputs as { type: string; components?: unknown[] }[]).map(formatType).join(','); + return `${abiItem.name}(${params})`; + } +} diff --git a/src/errors.spec.ts b/src/errors.spec.ts new file mode 100644 index 0000000..577449b --- /dev/null +++ b/src/errors.spec.ts @@ -0,0 +1,147 @@ +import { ResponseError } from '../generated-contracts'; +import { formatCreditsWarning, InsufficientCreditsError, parseCreditsError } from './errors'; + +// ─── InsufficientCreditsError ──────────────────────────────────────────────── + +describe('InsufficientCreditsError', () => { + it('is an instance of Error', () => { + const err = new InsufficientCreditsError(); + expect(err).toBeInstanceOf(Error); + expect(err).toBeInstanceOf(InsufficientCreditsError); + }); + + it('carries required and available when provided', () => { + const err = new InsufficientCreditsError(100, 45); + expect(err.required).toBe(100); + expect(err.available).toBe(45); + }); + + it('has undefined required/available when not provided', () => { + const err = new InsufficientCreditsError(); + expect(err.required).toBeUndefined(); + expect(err.available).toBeUndefined(); + }); + + it('has a descriptive message', () => { + const err = new InsufficientCreditsError(10, 3); + expect(err.message).toBe('Insufficient credits for operation'); + }); +}); + +// ─── parseCreditsError ──────────────────────────────────────────────────────── + +function makeResponseError(status: number, body: unknown): ResponseError { + const json = jest.fn().mockResolvedValue(body); + const clone = jest.fn().mockReturnValue({ json }); + const response = { status, clone } as unknown as Response; + return new ResponseError(response); +} + +function makeUnparsableResponseError(status: number): ResponseError { + const json = jest.fn().mockRejectedValue(new SyntaxError('Unexpected token')); + const clone = jest.fn().mockReturnValue({ json }); + const response = { status, clone } as unknown as Response; + return new ResponseError(response); +} + +describe('parseCreditsError', () => { + it('returns InsufficientCreditsError for HTTP 402 with balance fields', async () => { + const err = makeResponseError(402, { + statusCode: 402, + message: 'Insufficient credits for operation', + required: 50, + available: 10, + }); + const result = await parseCreditsError(err); + expect(result).toBeInstanceOf(InsufficientCreditsError); + expect(result?.required).toBe(50); + expect(result?.available).toBe(10); + }); + + it('returns InsufficientCreditsError for HTTP 402 even without balance fields', async () => { + const err = makeResponseError(402, { statusCode: 402, message: 'Insufficient credits for operation' }); + const result = await parseCreditsError(err); + expect(result).toBeInstanceOf(InsufficientCreditsError); + expect(result?.required).toBeUndefined(); + expect(result?.available).toBeUndefined(); + }); + + it('returns null for HTTP 404', async () => { + const err = makeResponseError(404, { statusCode: 404, message: 'Not found' }); + const result = await parseCreditsError(err); + expect(result).toBeNull(); + }); + + it('returns null for HTTP 500', async () => { + const err = makeResponseError(500, { statusCode: 500, message: 'Internal server error' }); + const result = await parseCreditsError(err); + expect(result).toBeNull(); + }); + + it('handles unparseable JSON body gracefully — still returns error on 402', async () => { + const err = makeUnparsableResponseError(402); + const result = await parseCreditsError(err); + expect(result).toBeInstanceOf(InsufficientCreditsError); + expect(result?.required).toBeUndefined(); + expect(result?.available).toBeUndefined(); + }); +}); + +// ─── formatCreditsWarning ──────────────────────────────────────────────────── + +describe('formatCreditsWarning', () => { + it('returns a fixed-width box — all lines have equal length', () => { + const box = formatCreditsWarning(100, 45); + const lines = box.split('\n'); + const lengths = lines.map((l) => l.length); + expect(new Set(lengths).size).toBe(1); + }); + + it('returns a fixed-width box without balance — all lines equal length', () => { + const box = formatCreditsWarning(); + const lines = box.split('\n'); + const lengths = lines.map((l) => l.length); + expect(new Set(lengths).size).toBe(1); + }); + + it('includes Required and Available lines when values are provided', () => { + const box = formatCreditsWarning(100, 45); + expect(box).toContain('Required: 100'); + expect(box).toContain('Available: 45'); + }); + + it('omits Required and Available lines when values are not provided', () => { + const box = formatCreditsWarning(); + expect(box).not.toContain('Required:'); + expect(box).not.toContain('Available:'); + }); + + it('includes b2binpay-sdk in the header', () => { + const box = formatCreditsWarning(); + expect(box).toContain('b2binpay-sdk'); + }); +}); + +// ─── console.warn integration ──────────────────────────────────────────────── + +describe('console.warn called with boxed message', () => { + it('warns when parseCreditsError returns a credits error and DefiClient re-throws', async () => { + const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); + + const err = makeResponseError(402, { required: 50, available: 10 }); + const creditsError = await parseCreditsError(err); + + if (creditsError) { + console.warn(formatCreditsWarning(creditsError.required, creditsError.available)); + } + + expect(warnSpy).toHaveBeenCalledTimes(1); + const warnArg: string = warnSpy.mock.calls[0][0] as string; + expect(warnArg).toContain('b2binpay-sdk'); + expect(warnArg).toContain('Insufficient credits'); + expect(warnArg).toContain('50'); + expect(warnArg).toContain('10'); + + warnSpy.mockRestore(); + }); +}); diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 0000000..de5afaf --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,59 @@ +import type { ResponseError } from '../generated-contracts'; + +const BOX_INNER_WIDTH = 52; + +export class InsufficientCreditsError extends Error { + override name = 'InsufficientCreditsError'; + + constructor( + public readonly required?: number, + public readonly available?: number, + ) { + super('Insufficient credits for operation'); + } +} + +export function formatCreditsWarning(required?: number, available?: number): string { + const pad = (text: string): string => `║ ${text.padEnd(BOX_INNER_WIDTH - 2)}║`; + const empty = pad(''); + const top = `╔${'═'.repeat(BOX_INNER_WIDTH)}╗`; + const divider = `╠${'═'.repeat(BOX_INNER_WIDTH)}╣`; + const bottom = `╚${'═'.repeat(BOX_INNER_WIDTH)}╝`; + + const header = '⚠ b2binpay-sdk warning'; + const headerPadded = header + .padStart(Math.floor((BOX_INNER_WIDTH - 2 + header.length) / 2)) + .padEnd(BOX_INNER_WIDTH - 2); + + const lines: string[] = [top, `║ ${headerPadded}║`, divider, pad('Insufficient credits')]; + + if (required !== undefined && available !== undefined) { + lines.push(empty); + lines.push(pad(`Required: ${required}`)); + lines.push(pad(`Available: ${available}`)); + } + + lines.push(bottom); + + return lines.join('\n'); +} + +export async function parseCreditsError(err: ResponseError): Promise { + if (err.response.status !== 402) { + return null; + } + + try { + const body: unknown = await err.response.clone().json(); + if (body !== null && typeof body === 'object') { + const { required, available } = body as Record; + const req = typeof required === 'number' ? required : undefined; + const avail = typeof available === 'number' ? available : undefined; + return new InsufficientCreditsError(req, avail); + } + } catch { + // body unreadable — still a credits error + } + + return new InsufficientCreditsError(); +} diff --git a/src/index.ts b/src/index.ts index 6df47a2..59505ac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ -export * from './abi'; +export { type AbiCacheEntry, AbiProvider } from './abi-provider'; export * from './api'; export * from './blockchain'; +export { InsufficientCreditsError } from './errors'; export * from './utils'; diff --git a/src/utils/index.ts b/src/utils/index.ts index d13d102..8f00037 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,12 @@ export * as transactions from './transactions'; +export { TRON_ADDRESS_LENGTH, TRON_ADDRESS_PREFIX, TRON_ZERO_ADDRESS, type TronAddress } from './tron-types'; +export { + NetworkType, + tronToEvmHex, + type ValidateTronAddressParams, + type ValidateTronAddressResult, + validateTronAddress, +} from './tron-validation'; export { type ValidateAddressAsset, type ValidateAddressParams, diff --git a/src/utils/transactions/builders.ts b/src/utils/transactions/builders.ts index f35dbb4..de8dc75 100644 --- a/src/utils/transactions/builders.ts +++ b/src/utils/transactions/builders.ts @@ -1,6 +1,5 @@ -import { type Address, concatHex, encodeFunctionData, type Hex } from 'viem'; -import type { QueueOperationResponseDto } from '../../../generated-contracts'; -import { MULTI_SIG_WALLET_ABI } from '../../abi/multi-sig-wallet'; +import { type Abi, type Address, concatHex, encodeFunctionData, type Hex } from 'viem'; +import type { CallDto, QueueOperationResponseDto } from '../../../generated-contracts'; export interface PreparedTransaction { readonly to: Address; @@ -16,12 +15,29 @@ export interface ExecuteQueueOperationInput { readonly operations: Array; readonly contractAddress: Address; readonly chainId: number; + readonly abi: Abi; +} + +/** Ensures a hex string has a `0x` prefix. Idempotent. */ +export function ensureHexPrefix(value: string): Hex { + return (value.startsWith('0x') ? value : `0x${value}`) as Hex; +} + +/** Normalizes raw `CallDto` from the API into a typed structure with defaults. */ +export function normalizeCalls(calls: CallDto[]): Array<{ to: string; value: string | number | bigint; data: string }> { + return calls.map((call) => ({ + to: call.to, + value: call.value ?? '0', + data: call.data ?? '0x', + })); } /** * Builds a multisig execute transaction payload for one or more queue operations. */ export function buildExecuteOperationsTransaction(input: ExecuteQueueOperationInput): PreparedTransaction { + const abi = input.abi; + const operations = input.operations.map((operation) => ({ calls: operation.calls.map((call) => ({ to: call.to as Address, @@ -33,7 +49,7 @@ export function buildExecuteOperationsTransaction(input: ExecuteQueueOperationIn })); const data = encodeFunctionData({ - abi: MULTI_SIG_WALLET_ABI, + abi, functionName: 'execute', args: [operations], }); diff --git a/src/utils/transactions/eip712.ts b/src/utils/transactions/eip712.ts index 9883788..cf497cb 100644 --- a/src/utils/transactions/eip712.ts +++ b/src/utils/transactions/eip712.ts @@ -1,7 +1,6 @@ -import type { Address, Hex, PublicClient, SignTypedDataParameters, TypedData, TypedDataDomain } from 'viem'; +import type { Abi, Address, Hex, PublicClient, SignTypedDataParameters, TypedData, TypedDataDomain } from 'viem'; import type { Account } from 'viem/accounts'; import type { CallDto, QueueOperationResponseDto } from '../../../generated-contracts'; -import { MULTI_SIG_WALLET_ABI } from '../../abi'; export const EXECUTE_EIP712_TYPES = { Execute: [ @@ -63,6 +62,7 @@ export interface CreateExecuteTypedDataParams { operation: QueueOperationResponseDto; contractAddress: Address; publicClient: PublicClient; + abi: Abi; domainOverride?: TypedDataDomain; } @@ -81,6 +81,7 @@ export async function createExecuteTypedData(params: CreateExecuteTypedDataParam (await fetchExecuteTypedDataDomain({ contractAddress: params.contractAddress, publicClient: params.publicClient, + abi: params.abi, })); return buildExecuteTypedData({ domain, message }); @@ -89,21 +90,22 @@ export async function createExecuteTypedData(params: CreateExecuteTypedDataParam export interface FetchExecuteTypedDataDomainParams { contractAddress: Address; publicClient: PublicClient; + abi: Abi; } export async function fetchExecuteTypedDataDomain(params: FetchExecuteTypedDataDomainParams): Promise { - const { contractAddress, publicClient } = params; + const { contractAddress, publicClient, abi } = params; - const domainTuple = await publicClient.readContract({ + const domainTuple = (await publicClient.readContract({ address: contractAddress, - abi: MULTI_SIG_WALLET_ABI, + abi, functionName: 'eip712Domain', - }); + })) as readonly [Hex, string, string, bigint, Address, Hex, readonly bigint[]]; - const domainName = domainTuple[1] as string; - const domainVersion = domainTuple[2] as string; - const domainChainId = domainTuple[3] as bigint; - const verifyingContract = domainTuple[4] as Address; + const domainName = domainTuple[1]; + const domainVersion = domainTuple[2]; + const domainChainId = domainTuple[3]; + const verifyingContract = domainTuple[4]; return { name: domainName, diff --git a/src/utils/transactions/index.ts b/src/utils/transactions/index.ts index 40e7383..280fd7d 100644 --- a/src/utils/transactions/index.ts +++ b/src/utils/transactions/index.ts @@ -1,2 +1,5 @@ export * from './builders'; export * from './eip712'; +export * from './signatures'; +export * from './tron-tip712'; +export * from './tron-tip712-types'; diff --git a/src/utils/transactions/signatures.spec.ts b/src/utils/transactions/signatures.spec.ts new file mode 100644 index 0000000..0f7ff3e --- /dev/null +++ b/src/utils/transactions/signatures.spec.ts @@ -0,0 +1,140 @@ +import type { Address, Hex } from 'viem'; +import { hexToBytes } from 'viem'; +import { packSignatures, type SignatureEntry } from './signatures'; + +// Test fixtures: deterministic addresses and 65-byte ECDSA signatures +const SIGNER_A: Address = '0x1111111111111111111111111111111111111111'; +const SIGNER_B: Address = '0x2222222222222222222222222222222222222222'; +const SIGNER_C: Address = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; + +const SIG_A: Hex = `0x${'aa'.repeat(65)}` as Hex; +const SIG_B: Hex = `0x${'bb'.repeat(65)}` as Hex; +const SIG_C: Hex = `0x${'cc'.repeat(65)}` as Hex; + +function entry(user: Address, sign: Hex): SignatureEntry { + return { user, sign }; +} + +describe('packSignatures', () => { + describe('v1.0.0 — simple concatenation', () => { + it('concatenates single signature', () => { + const result = packSignatures([entry(SIGNER_A, SIG_A)], '1.0.0'); + expect(result).toBe(SIG_A); + }); + + it('concatenates multiple signatures in order', () => { + const result = packSignatures([entry(SIGNER_A, SIG_A), entry(SIGNER_B, SIG_B)], '1.0.0'); + expect(result).toBe(`0x${'aa'.repeat(65)}${'bb'.repeat(65)}`); + }); + + it('does not sort by address', () => { + const result = packSignatures([entry(SIGNER_B, SIG_B), entry(SIGNER_A, SIG_A)], '1.0.0'); + // B first, then A — preserves input order + expect(result).toBe(`0x${'bb'.repeat(65)}${'aa'.repeat(65)}`); + }); + }); + + describe('v1.1.0 — packed binary format', () => { + it('packs single signature correctly', () => { + const result = packSignatures([entry(SIGNER_A, SIG_A)], '1.1.0'); + const bytes = hexToBytes(result); + + // 20 (address) + 2 (uint16 len) + 65 (sig) = 87 + expect(bytes.length).toBe(87); + + // address + expect(bytes.slice(0, 20)).toEqual(hexToBytes(SIGNER_A)); + + // uint16 BE length = 65 = 0x0041 + expect(bytes[20]).toBe(0x00); + expect(bytes[21]).toBe(0x41); + + // signature + expect(bytes.slice(22, 87)).toEqual(hexToBytes(SIG_A)); + }); + + it('sorts by signer address ascending', () => { + // Pass in reverse order: C, B, A + const result = packSignatures([entry(SIGNER_C, SIG_C), entry(SIGNER_A, SIG_A), entry(SIGNER_B, SIG_B)], '1.1.0'); + const bytes = hexToBytes(result); + + // 3 entries * 87 bytes each + expect(bytes.length).toBe(87 * 3); + + // First entry should be SIGNER_A (lowest address) + expect(bytes.slice(0, 20)).toEqual(hexToBytes(SIGNER_A)); + // Second should be SIGNER_B + expect(bytes.slice(87, 87 + 20)).toEqual(hexToBytes(SIGNER_B)); + // Third should be SIGNER_C + expect(bytes.slice(87 * 2, 87 * 2 + 20)).toEqual(hexToBytes(SIGNER_C)); + }); + + it('encodes uint16 big-endian length correctly for longer signatures', () => { + // 256-byte signature to test BE encoding + const longSig: Hex = `0x${'ff'.repeat(256)}` as Hex; + const result = packSignatures([entry(SIGNER_A, longSig)], '1.1.0'); + const bytes = hexToBytes(result); + + // 20 + 2 + 256 = 278 + expect(bytes.length).toBe(278); + + // 256 = 0x0100 in big-endian + expect(bytes[20]).toBe(0x01); + expect(bytes[21]).toBe(0x00); + }); + + it('throws on duplicate signer addresses', () => { + expect(() => packSignatures([entry(SIGNER_A, SIG_A), entry(SIGNER_A, SIG_B)], '1.1.0')).toThrow( + 'Duplicate signer addresses detected', + ); + }); + + it('throws on duplicate addresses with different casing', () => { + const signerUpper = SIGNER_A.toUpperCase().replace('0X', '0x') as Address; + expect(() => packSignatures([entry(SIGNER_A, SIG_A), entry(signerUpper, SIG_B)], '1.1.0')).toThrow( + 'Duplicate signer addresses detected', + ); + }); + }); + + describe('version selection', () => { + it('uses v1.0.0 packing for version "1.0.0"', () => { + const result = packSignatures([entry(SIGNER_B, SIG_B), entry(SIGNER_A, SIG_A)], '1.0.0'); + // v1.0.0 does simple concat without sorting — B then A + expect(result).toBe(`0x${'bb'.repeat(65)}${'aa'.repeat(65)}`); + }); + + it('uses v1.1.0 packing for version "1.1.0"', () => { + const result = packSignatures([entry(SIGNER_A, SIG_A)], '1.1.0'); + const bytes = hexToBytes(result); + // v1.1.0 includes address + length prefix = 87 bytes, not 65 + expect(bytes.length).toBe(87); + }); + + it('falls back to v1.1.0 for unknown versions with console warning', () => { + const warnSpy = jest.spyOn(console, 'warn').mockImplementation(); + + const result = packSignatures([entry(SIGNER_A, SIG_A)], '2.0.0'); + const bytes = hexToBytes(result); + + // Should use v1.1.0 format + expect(bytes.length).toBe(87); + + expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Unknown contract version "2.0.0"')); + + warnSpy.mockRestore(); + }); + }); + + describe('edge cases', () => { + it('handles empty signatures array for v1.0.0', () => { + const result = packSignatures([], '1.0.0'); + expect(result).toBe('0x'); + }); + + it('handles empty signatures array for v1.1.0', () => { + const result = packSignatures([], '1.1.0'); + expect(result).toBe('0x'); + }); + }); +}); diff --git a/src/utils/transactions/signatures.ts b/src/utils/transactions/signatures.ts new file mode 100644 index 0000000..ee8fdbe --- /dev/null +++ b/src/utils/transactions/signatures.ts @@ -0,0 +1,86 @@ +import { type Address, bytesToHex, concatHex, type Hex, hexToBytes } from 'viem'; + +/** + * Supported MultiSigWallet contract versions. + */ +export type ContractVersion = '1.0.0' | '1.1.0'; + +export const SUPPORTED_CONTRACT_VERSIONS: readonly ContractVersion[] = ['1.0.0', '1.1.0']; + +export interface SignatureEntry { + /** Signer address */ + readonly user: Address; + /** Hex-encoded signature */ + readonly sign: Hex; +} + +/** + * Packs an array of signatures into a single hex blob using the format appropriate + * for the given contract version. + * + * - **v1.0.0**: Simple concatenation of 65-byte ECDSA signatures. + * - **v1.1.0**: Packed binary format `[signer:20 bytes][sigLen:2 bytes uint16 BE][sig:sigLen bytes]` + * per entry, sorted by signer address in strictly ascending order. + */ +export function packSignatures(signatures: ReadonlyArray, contractVersion: string): Hex { + switch (contractVersion) { + case '1.0.0': + return packSignaturesV1(signatures); + case '1.1.0': + return packSignaturesV1_1(signatures); + default: + console.warn( + `[defi-sdk] Unknown contract version "${contractVersion}" in packSignatures. ` + + 'Using v1.1.0 signature format as fallback.', + ); + return packSignaturesV1_1(signatures); + } +} + +/** + * v1.0.0 signature packing: simple concatenation of raw signatures. + */ +function packSignaturesV1(signatures: ReadonlyArray): Hex { + return concatHex(signatures.map((sig) => sig.sign as Hex)); +} + +/** + * v1.1.0 signature packing: packed binary format with explicit signer addresses. + * + * Format per entry: `[signer:20 bytes][sigLen:2 bytes uint16 BE][sig:sigLen bytes]` + * Entries are sorted by signer address in strictly ascending order. + */ +function packSignaturesV1_1(signatures: ReadonlyArray): Hex { + const uniqueSigners = new Set(signatures.map((s) => s.user.toLowerCase())); + if (uniqueSigners.size !== signatures.length) { + throw new Error('Duplicate signer addresses detected in signatures array'); + } + + const sorted = [...signatures].sort((a, b) => { + const addrA = a.user.toLowerCase(); + const addrB = b.user.toLowerCase(); + return addrA < addrB ? -1 : addrA > addrB ? 1 : 0; + }); + + const parts: Uint8Array[] = []; + + for (const entry of sorted) { + const addressBytes = hexToBytes(entry.user); + const sigBytes = hexToBytes(entry.sign); + + const lenBytes = new Uint8Array(2); + new DataView(lenBytes.buffer).setUint16(0, sigBytes.length, false); + + parts.push(addressBytes, lenBytes, sigBytes); + } + + const totalLength = parts.reduce((sum, part) => sum + part.length, 0); + const result = new Uint8Array(totalLength); + let offset = 0; + for (const part of parts) { + result.set(part, offset); + offset += part.length; + } + + return bytesToHex(result); +} diff --git a/src/utils/transactions/tron-tip712-types.ts b/src/utils/transactions/tron-tip712-types.ts new file mode 100644 index 0000000..cd87549 --- /dev/null +++ b/src/utils/transactions/tron-tip712-types.ts @@ -0,0 +1,61 @@ +import type { TronWeb } from 'tronweb'; +import type { Abi, Hex } from 'viem'; +import type { TronAddress } from '../tron-types'; + +export const TRON_EXECUTE_TIP712_TYPES = { + Execute: [ + { name: 'calls', type: 'Call[]' }, + { name: 'nonce', type: 'uint256' }, + ], + Call: [ + { name: 'to', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + ], +} as const; + +export const TRON_EXECUTE_PRIMARY_TYPE = 'Execute' as const; + +export interface TronExecuteTypedCall { + to: TronAddress; + value: bigint; + data: string; +} + +export interface TronExecuteTypedMessage { + calls: TronExecuteTypedCall[]; + nonce: bigint; +} + +export interface TronExecuteTypedDataPayload { + readonly domain: { + readonly name: string; + readonly version: string; + readonly chainId: bigint; + readonly verifyingContract: TronAddress; + }; + readonly types: typeof TRON_EXECUTE_TIP712_TYPES; + readonly primaryType: typeof TRON_EXECUTE_PRIMARY_TYPE; + readonly message: TronExecuteTypedMessage; +} + +export interface FetchTronExecuteTypedDataDomainParams { + tronWeb: TronWeb; + contractAddress: TronAddress; + abi: Abi; +} + +/** + * TronWeb-compatible typed data structure where BigInt values are converted + * to plain types (number/string) for `TronWeb.trx._signTypedData()`. + */ +export interface TronSignableTypedData { + domain: { name: string; version: string; chainId: string; verifyingContract: string }; + types: Record>; + message: { calls: Array<{ to: string; value: string; data: string }>; nonce: string }; +} + +export interface TronSignatureEntry { + readonly signer: TronAddress; + readonly signature: Hex; +} diff --git a/src/utils/transactions/tron-tip712.spec.ts b/src/utils/transactions/tron-tip712.spec.ts new file mode 100644 index 0000000..ec51fea --- /dev/null +++ b/src/utils/transactions/tron-tip712.spec.ts @@ -0,0 +1,118 @@ +import type { Hex } from 'viem'; +import type { TronAddress } from '../tron-validation'; +import { + buildTronExecuteTypedData, + packTronSignatures, + TRON_EXECUTE_TIP712_TYPES, + type TronExecuteTypedDataPayload, +} from './tron-tip712'; + +const CONTRACT: TronAddress = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t' as TronAddress; +const RECIPIENT: TronAddress = 'TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL' as TronAddress; + +const SIGNER_A: TronAddress = 'TJCnKsPa7y5okkXvQAidZBzqx3QyQ6sxMW' as TronAddress; +const SIGNER_B: TronAddress = 'TVjsyZ7fYF3qLF6BQgPmTEZy1xrNNyVAAA' as TronAddress; + +const SIG_A = `0x${'aa'.repeat(65)}` as Hex; +const SIG_B = `0x${'bb'.repeat(65)}` as Hex; + +describe('TRON_EXECUTE_TIP712_TYPES', () => { + it('has Execute and Call types matching EIP-712 structure', () => { + expect(TRON_EXECUTE_TIP712_TYPES.Execute).toEqual([ + { name: 'calls', type: 'Call[]' }, + { name: 'nonce', type: 'uint256' }, + ]); + expect(TRON_EXECUTE_TIP712_TYPES.Call).toEqual([ + { name: 'to', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'data', type: 'bytes' }, + ]); + }); +}); + +describe('buildTronExecuteTypedData', () => { + const domain: TronExecuteTypedDataPayload['domain'] = { + name: 'MultiSigWallet', + version: '1.0.0', + chainId: 728126428n, + verifyingContract: CONTRACT, + }; + + it('builds correct TIP-712 payload structure', () => { + const result = buildTronExecuteTypedData({ + domain, + calls: [{ to: RECIPIENT, value: 1000n, data: '0x' }], + nonce: 1n, + }); + + expect(result.primaryType).toBe('Execute'); + expect(result.types).toBe(TRON_EXECUTE_TIP712_TYPES); + expect(result.domain).toBe(domain); + expect(result.message.nonce).toBe(1n); + expect(result.message.calls).toHaveLength(1); + expect(result.message.calls[0].to).toBe(RECIPIENT); + expect(result.message.calls[0].value).toBe(1000n); + expect(result.message.calls[0].data).toBe('0x'); + }); + + it('handles multiple calls', () => { + const result = buildTronExecuteTypedData({ + domain, + calls: [ + { to: RECIPIENT, value: 100n, data: '0xabcd' }, + { to: CONTRACT, value: 0n, data: '0x1234' }, + ], + nonce: 5n, + }); + + expect(result.message.calls).toHaveLength(2); + expect(result.message.nonce).toBe(5n); + }); +}); + +describe('packTronSignatures', () => { + describe('v1.0.0 — simple concatenation', () => { + it('concatenates single signature', () => { + const result = packTronSignatures([{ signer: SIGNER_A, signature: SIG_A }], '1.0.0'); + expect(result).toBe(SIG_A); + }); + + it('concatenates multiple signatures in order', () => { + const result = packTronSignatures( + [ + { signer: SIGNER_A, signature: SIG_A }, + { signer: SIGNER_B, signature: SIG_B }, + ], + '1.0.0', + ); + expect(result).toBe(`0x${'aa'.repeat(65)}${'bb'.repeat(65)}`); + }); + }); + + describe('v1.1.0 — packed binary format', () => { + it('packs single signature with signer address', () => { + const result = packTronSignatures([{ signer: SIGNER_A, signature: SIG_A }], '1.1.0'); + // Should be hex string with 20 (address) + 2 (len) + 65 (sig) = 87 bytes + // 0x prefix + 87*2 hex chars = 176 chars + expect(result.startsWith('0x')).toBe(true); + expect((result.length - 2) / 2).toBe(87); + }); + + it('sorts by signer address ascending', () => { + const result = packTronSignatures( + [ + { signer: SIGNER_B, signature: SIG_B }, + { signer: SIGNER_A, signature: SIG_A }, + ], + '1.1.0', + ); + // 2 entries * 87 bytes + expect((result.length - 2) / 2).toBe(87 * 2); + }); + + it('handles empty signatures array', () => { + const result = packTronSignatures([], '1.1.0'); + expect(result).toBe('0x'); + }); + }); +}); diff --git a/src/utils/transactions/tron-tip712.ts b/src/utils/transactions/tron-tip712.ts new file mode 100644 index 0000000..a4eddd0 --- /dev/null +++ b/src/utils/transactions/tron-tip712.ts @@ -0,0 +1,145 @@ +import { TronWeb } from 'tronweb'; +import { bytesToHex, concatHex, type Hex, hexToBytes } from 'viem'; +import type { TronAddress } from '../tron-types'; +import { tronToEvmHex } from '../tron-validation'; +import { + type FetchTronExecuteTypedDataDomainParams, + TRON_EXECUTE_PRIMARY_TYPE, + TRON_EXECUTE_TIP712_TYPES, + type TronExecuteTypedCall, + type TronExecuteTypedDataPayload, + type TronSignableTypedData, + type TronSignatureEntry, +} from './tron-tip712-types'; + +export * from './tron-tip712-types'; + +/** + * Converts an EVM hex address (0x...) to a Tron Base58Check address (T...). + * Used when building TIP-712 typed data where address fields must be in Tron format. + */ +function hexToTronAddress(hexAddress: string): TronAddress { + // If already a Tron base58 address, return as-is + if (hexAddress.startsWith('T')) return hexAddress as TronAddress; + // Convert 0x-prefixed EVM hex to 41-prefixed Tron hex, then to base58 + const tronHex = `41${hexAddress.replace(/^0x/, '')}`; + return TronWeb.address.fromHex(tronHex) as TronAddress; +} + +export function buildTronExecuteTypedData(params: { + domain: TronExecuteTypedDataPayload['domain']; + calls: ReadonlyArray; + nonce: bigint; +}): TronExecuteTypedDataPayload { + return { + domain: params.domain, + primaryType: TRON_EXECUTE_PRIMARY_TYPE, + types: TRON_EXECUTE_TIP712_TYPES, + message: { + calls: params.calls.map((call) => ({ + to: hexToTronAddress(call.to), + value: call.value, + data: call.data, + })), + nonce: params.nonce, + }, + }; +} + +export async function fetchTronExecuteTypedDataDomain( + params: FetchTronExecuteTypedDataDomainParams, +): Promise { + const { tronWeb, contractAddress, abi } = params; + + const contract = tronWeb.contract(abi as Parameters[0], contractAddress); + const domainTuple = await contract.eip712Domain().call(); + + return { + name: domainTuple[1] as string, + version: domainTuple[2] as string, + chainId: BigInt(domainTuple[3] as string), + verifyingContract: domainTuple[4] as TronAddress, + }; +} + +/** + * Prepares TIP-712 typed data for signing with TronWeb.trx._signTypedData(). + * Converts BigInt values to plain types compatible with TronWeb's signing method: + * - domain.chainId: bigint → number + * - message.nonce and call values: bigint → string + */ +export function prepareTronTypedDataForSigning(typedData: TronExecuteTypedDataPayload): TronSignableTypedData { + return { + domain: { + ...typedData.domain, + chainId: typedData.domain.chainId.toString(), + verifyingContract: typedData.domain.verifyingContract as string, + }, + types: typedData.types as unknown as Record>, + message: { + calls: typedData.message.calls.map((call) => ({ + to: call.to as string, + value: call.value.toString(), + data: call.data, + })), + nonce: typedData.message.nonce.toString(), + }, + }; +} + +export function packTronSignatures(signatures: ReadonlyArray, contractVersion: string): Hex { + switch (contractVersion) { + case '1.0.0': + return packTronSignaturesV1(signatures); + case '1.1.0': + return packTronSignaturesV1_1(signatures); + default: + console.warn( + `[defi-sdk] Unknown contract version "${contractVersion}" in packTronSignatures. ` + + 'Using v1.1.0 signature format as fallback.', + ); + return packTronSignaturesV1_1(signatures); + } +} + +function packTronSignaturesV1(signatures: ReadonlyArray): Hex { + if (signatures.length === 0) return '0x' as Hex; + return concatHex(signatures.map((s) => s.signature)); +} + +function packTronSignaturesV1_1(signatures: ReadonlyArray): Hex { + if (signatures.length === 0) return '0x' as Hex; + + // Pre-compute hex keys to avoid repeated base58 decoding in sort comparator + const withHex = signatures.map((entry) => ({ + entry, + evmHex: tronToEvmHex(entry.signer), + })); + withHex.sort((a, b) => { + const hexA = a.evmHex.toLowerCase(); + const hexB = b.evmHex.toLowerCase(); + return hexA < hexB ? -1 : hexA > hexB ? 1 : 0; + }); + + const parts: Uint8Array[] = []; + + for (const { entry, evmHex } of withHex) { + const addressBytes = hexToBytes(evmHex); + const sigBytes = hexToBytes(entry.signature); + + const lenBytes = new Uint8Array(2); + new DataView(lenBytes.buffer).setUint16(0, sigBytes.length, false); + + parts.push(addressBytes, lenBytes, sigBytes); + } + + const totalLength = parts.reduce((sum, part) => sum + part.length, 0); + const result = new Uint8Array(totalLength); + let offset = 0; + for (const part of parts) { + result.set(part, offset); + offset += part.length; + } + + return bytesToHex(result); +} diff --git a/src/utils/tron-types.ts b/src/utils/tron-types.ts new file mode 100644 index 0000000..e993299 --- /dev/null +++ b/src/utils/tron-types.ts @@ -0,0 +1,11 @@ +import { TronWeb } from 'tronweb'; +import { zeroAddress } from 'viem'; + +/** Branded type for Tron Base58Check addresses */ +export type TronAddress = string & { readonly __brand: 'TronAddress' }; + +export const TRON_ADDRESS_PREFIX = 'T'; +export const TRON_ADDRESS_LENGTH = 34; + +/** Tron zero address — EVM zeroAddress converted to Tron format (0x → 41 prefix). Used for native TRX in claim calls. */ +export const TRON_ZERO_ADDRESS = TronWeb.address.fromHex(zeroAddress.replace('0x', '41')) as TronAddress; diff --git a/src/utils/tron-validation.spec.ts b/src/utils/tron-validation.spec.ts new file mode 100644 index 0000000..1bd49c8 --- /dev/null +++ b/src/utils/tron-validation.spec.ts @@ -0,0 +1,91 @@ +import { validateTronAddress } from './tron-validation'; + +// Known valid Tron mainnet address (USDT contract) +const VALID_ADDRESS = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'; +// Another valid address +const VALID_ADDRESS_2 = 'TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL'; + +describe('validateTronAddress', () => { + describe('valid addresses', () => { + it('validates a correct Tron mainnet address', () => { + const result = validateTronAddress({ address: VALID_ADDRESS }); + expect(result.isValid).toBe(true); + expect(result.errors).toEqual([]); + expect(result.normalizedAddress).toBe(VALID_ADDRESS); + }); + + it('validates another correct Tron address', () => { + const result = validateTronAddress({ address: VALID_ADDRESS_2 }); + expect(result.isValid).toBe(true); + expect(result.errors).toEqual([]); + expect(result.normalizedAddress).toBe(VALID_ADDRESS_2); + }); + + it('returns branded TronAddress type', () => { + const result = validateTronAddress({ address: VALID_ADDRESS }); + expect(typeof result.normalizedAddress).toBe('string'); + expect(result.normalizedAddress).toBeDefined(); + }); + }); + + describe('invalid addresses', () => { + it('rejects address with wrong prefix (not T)', () => { + const result = validateTronAddress({ address: 'AR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t' }); + expect(result.isValid).toBe(false); + expect(result.errors.length).toBeGreaterThan(0); + expect(result.normalizedAddress).toBeUndefined(); + }); + + it('rejects address with incorrect length (too short)', () => { + const result = validateTronAddress({ address: 'TR7NHqjeKQx' }); + expect(result.isValid).toBe(false); + expect(result.errors.length).toBeGreaterThan(0); + expect(result.normalizedAddress).toBeUndefined(); + }); + + it('rejects address with incorrect length (too long)', () => { + const result = validateTronAddress({ address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6tXXX' }); + expect(result.isValid).toBe(false); + expect(result.errors.length).toBeGreaterThan(0); + expect(result.normalizedAddress).toBeUndefined(); + }); + + it('rejects address with bad checksum', () => { + // Modify last character to break checksum + const badChecksum = `${VALID_ADDRESS.slice(0, -1)}z`; + const result = validateTronAddress({ address: badChecksum }); + expect(result.isValid).toBe(false); + expect(result.errors.length).toBeGreaterThan(0); + expect(result.normalizedAddress).toBeUndefined(); + }); + + it('rejects empty string', () => { + const result = validateTronAddress({ address: '' }); + expect(result.isValid).toBe(false); + expect(result.errors).toContain('Address is required.'); + expect(result.normalizedAddress).toBeUndefined(); + }); + + it('rejects an EVM address', () => { + const result = validateTronAddress({ address: '0x1111111111111111111111111111111111111111' }); + expect(result.isValid).toBe(false); + expect(result.errors.length).toBeGreaterThan(0); + expect(result.normalizedAddress).toBeUndefined(); + }); + + it('rejects hex-format Tron address (41-prefixed)', () => { + const result = validateTronAddress({ address: '418840E6C55B9ADA326D211D818C34A994AECED808' }); + expect(result.isValid).toBe(false); + expect(result.errors.length).toBeGreaterThan(0); + expect(result.normalizedAddress).toBeUndefined(); + }); + }); + + describe('error messages', () => { + it('provides descriptive error for invalid format', () => { + const result = validateTronAddress({ address: 'invalid' }); + expect(result.errors[0]).toContain('Tron'); + expect(result.errors[0]).toContain('Base58Check'); + }); + }); +}); diff --git a/src/utils/tron-validation.ts b/src/utils/tron-validation.ts new file mode 100644 index 0000000..df49d41 --- /dev/null +++ b/src/utils/tron-validation.ts @@ -0,0 +1,48 @@ +import { TronWeb } from 'tronweb'; +import { TRON_ADDRESS_LENGTH, TRON_ADDRESS_PREFIX, type TronAddress } from './tron-types'; + +export { TRON_ADDRESS_LENGTH, TRON_ADDRESS_PREFIX, TRON_ZERO_ADDRESS, type TronAddress } from './tron-types'; + +export enum NetworkType { + EVM = 'evm', + TVM = 'tvm', +} + +export interface ValidateTronAddressParams { + address: string; +} + +export interface ValidateTronAddressResult { + isValid: boolean; + errors: string[]; + normalizedAddress?: TronAddress; +} + +/** Converts a Tron Base58Check address (T...) to a 20-byte EVM hex address (0x...). */ +export function tronToEvmHex(address: string): `0x${string}` { + return `0x${TronWeb.address.toHex(address).slice(2)}`; +} + +export function validateTronAddress(params: ValidateTronAddressParams): ValidateTronAddressResult { + const errors: string[] = []; + + if (!params.address) { + return { isValid: false, errors: ['Address is required.'], normalizedAddress: undefined }; + } + + if (params.address.length !== TRON_ADDRESS_LENGTH || !params.address.startsWith(TRON_ADDRESS_PREFIX)) { + errors.push('Address must be a valid Tron Base58Check address (T-prefix, 34 chars).'); + return { isValid: false, errors, normalizedAddress: undefined }; + } + + if (!TronWeb.isAddress(params.address)) { + errors.push('Address must be a valid Tron Base58Check address (T-prefix, 34 chars).'); + return { isValid: false, errors, normalizedAddress: undefined }; + } + + return { + isValid: true, + errors: [], + normalizedAddress: params.address as TronAddress, + }; +} diff --git a/src/utils/validation.spec.ts b/src/utils/validation.spec.ts new file mode 100644 index 0000000..4ffde26 --- /dev/null +++ b/src/utils/validation.spec.ts @@ -0,0 +1,74 @@ +import { NetworkType } from './tron-validation'; +import { validateAddress } from './validation'; + +describe('validateAddress — extended with Tron support', () => { + describe('EVM backward compatibility', () => { + it('validates a valid EVM address without networkType', () => { + const result = validateAddress({ address: '0x1111111111111111111111111111111111111111' }); + expect(result.isValid).toBe(true); + expect(result.normalizedAddress).toBeDefined(); + expect(result.errors).toEqual([]); + }); + + it('rejects an invalid EVM address without networkType', () => { + const result = validateAddress({ address: '0xinvalid' }); + expect(result.isValid).toBe(false); + expect(result.errors.length).toBeGreaterThan(0); + }); + + it('rejects empty address', () => { + const result = validateAddress({ address: '' }); + expect(result.isValid).toBe(false); + expect(result.errors).toContain('Address is required.'); + }); + }); + + describe('auto-detection', () => { + it('auto-detects Tron address (T prefix, 34 chars)', () => { + const result = validateAddress({ address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t' }); + expect(result.isValid).toBe(true); + expect(result.normalizedAddress).toBe('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'); + }); + + it('auto-detects EVM address (0x prefix)', () => { + const result = validateAddress({ address: '0x1111111111111111111111111111111111111111' }); + expect(result.isValid).toBe(true); + }); + }); + + describe('network type cross-validation', () => { + it('rejects Tron address on EVM network', () => { + const result = validateAddress({ + address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', + networkType: NetworkType.EVM, + }); + expect(result.isValid).toBe(false); + expect(result.errors[0]).toContain('mismatch'); + }); + + it('rejects EVM address on Tron network', () => { + const result = validateAddress({ + address: '0x1111111111111111111111111111111111111111', + networkType: NetworkType.TVM, + }); + expect(result.isValid).toBe(false); + expect(result.errors[0]).toContain('mismatch'); + }); + + it('accepts Tron address on TVM network', () => { + const result = validateAddress({ + address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', + networkType: NetworkType.TVM, + }); + expect(result.isValid).toBe(true); + }); + + it('accepts EVM address on EVM network', () => { + const result = validateAddress({ + address: '0x1111111111111111111111111111111111111111', + networkType: NetworkType.EVM, + }); + expect(result.isValid).toBe(true); + }); + }); +}); diff --git a/src/utils/validation.ts b/src/utils/validation.ts index 249a0d2..ee0b203 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -1,6 +1,13 @@ import type { Address } from 'viem'; import { getAddress, isAddress } from 'viem'; import type { CurrencyResponseDto } from '../../generated-contracts'; +import { + NetworkType, + TRON_ADDRESS_LENGTH, + TRON_ADDRESS_PREFIX, + type TronAddress, + validateTronAddress, +} from './tron-validation'; export interface ValidateAddressAsset { currencyId: string; @@ -13,12 +20,13 @@ export interface ValidateAddressParams { currency?: Pick; assets?: ValidateAddressAsset[]; allowedNetworks?: Array; + networkType?: NetworkType; } export interface ValidateAddressResult { isValid: boolean; errors: string[]; - normalizedAddress?: Address; + normalizedAddress?: Address | TronAddress; } const normalizeChainId = (value?: string | number): string | undefined => { @@ -29,16 +37,37 @@ const normalizeChainId = (value?: string | number): string | undefined => { return typeof value === 'number' ? value.toString() : value; }; +function isTronAddressFormat(address: string): boolean { + return address.startsWith(TRON_ADDRESS_PREFIX) && address.length === TRON_ADDRESS_LENGTH; +} + export function validateAddress(params: ValidateAddressParams): ValidateAddressResult { const errors: string[] = []; - let normalizedAddress: Address | undefined; + let normalizedAddress: Address | TronAddress | undefined; if (!params.address) { errors.push('Address is required.'); - } else if (!isAddress(params.address)) { - errors.push('Address must be a valid EVM address.'); } else { - normalizedAddress = getAddress(params.address); + const detectedTron = isTronAddressFormat(params.address); + + // Cross-validate network type vs address format + if (params.networkType === NetworkType.EVM && detectedTron) { + errors.push('Address type mismatch: Tron address provided for EVM network.'); + } else if (params.networkType === NetworkType.TVM && !detectedTron) { + errors.push('Address type mismatch: EVM address provided for Tron network.'); + } else if (detectedTron) { + // Tron validation path + const tronResult = validateTronAddress({ address: params.address }); + if (!tronResult.isValid) { + errors.push(...tronResult.errors); + } else { + normalizedAddress = tronResult.normalizedAddress; + } + } else if (!isAddress(params.address)) { + errors.push('Address must be a valid EVM address.'); + } else { + normalizedAddress = getAddress(params.address); + } } const requestedChainId = normalizeChainId(params.networkChainId); diff --git a/tsconfig.build.json b/tsconfig.build.json index 30e73d4..45f0014 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -12,5 +12,5 @@ "types": ["node"] }, "include": ["src/**/*.ts", "generated-contracts/**/*.ts"], - "exclude": ["examples/**", "dist/**", "node_modules/**"] + "exclude": ["examples/**", "dist/**", "node_modules/**", "**/*.spec.ts", "**/*.test.ts"] } diff --git a/tsconfig.json b/tsconfig.json index be9bd01..19d9553 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ "skipLibCheck": true, "noEmit": true, "lib": ["ES2022", "DOM"], - "types": ["node"] + "types": ["node", "jest"] }, "include": ["src/**/*.ts", "examples/**/*.ts", "generated-contracts/**/*.ts"] }