diff --git a/README.md b/README.md index a71d884..985cbc6 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,19 @@ surface, with a code example and return type, see the ## Installation +In the mobile app: + +```sh +npm install kokio-sdk react-native-passkey +``` + +On a backend that only uses `kokio-sdk/admin`: + ```sh npm install kokio-sdk ``` -The package ships as ES modules and requires Node 18 or newer (or a React Native -runtime). `viem` is bundled as a dependency, so you do not need to install it -separately. +The package ships as ES modules and requires Node 18 or newer (or a React Native runtime). `viem` is bundled as a dependency, so you do not need to install it separately. `react-native-passkey` is a native module, so the app installs it itself: Expo only links native modules the app lists directly, and one copy avoids version clashes. ## Mobile client (Expo / React Native) @@ -39,10 +45,9 @@ is ever held in the app. You will need: -- a viem `WalletClient` connected to the target chain, carrying an `account` - and an explicit RPC URL (see the note under the example), +- a viem `WalletClient` connected to the target chain with an explicit RPC URL (see the note under the example). It needs no `account`: the passkey signs every user operation. - the passkey `credentialId` and `rpId` registered for the device, -- a Pimlico API key and a gas policy id (used by the bundler and paymaster). +- a Pimlico API key, and optionally a Pimlico sponsorship policy id (`sp_...`). Pass `""` to be sponsored without a policy. ```ts import { Kokio } from "kokio-sdk"; @@ -50,7 +55,6 @@ import { createWalletClient, http } from "viem"; import { baseSepolia } from "viem/chains"; const walletClient = createWalletClient({ - account: knownAddress, chain: baseSepolia, transport: http(rpcUrl), }); @@ -90,15 +94,11 @@ const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash }); if (!receipt.success) throw new Error("operation reverted"); ``` -Two things about the wallet client. It has to carry an `account`: -`getSmartWallet` refuses a client without one, though it never asks it for a -signature, since the passkey signs everything. And give `http()` a real RPC -URL, because the SDK reads `client.transport.url` to build the public client -it uses for contract reads. +The wallet client needs no `account`, since the passkey signs everything. Give `http()` a real RPC URL, because the SDK reads `client.transport.url` to build the public client it uses for contract reads. + +Every write resolves with the user operation hash once the bundler accepts it, not once it is mined, so wait for the receipt as above. An operation the bundler can see will revert is refused before it is sent, and the write rejects with a `ContractRevertError` whose `decoded.errorName` names the contract error (for example `PaymentReferenceAlreadyUsed`). One that only reverts once mined still returns a receipt, so check `receipt.success` too. `receipt.receipt.transactionHash` is the onchain transaction. -Check `receipt.success`. An operation whose calls revert is still mined and -still returns a receipt, so the await resolving is not on its own proof the -write landed. `receipt.receipt.transactionHash` is the onchain transaction. +Calls that belong together have helpers that send them as one user operation, so the user sees one passkey prompt: `deviceWallet.deployAndBindESIMWallet(salt, { grantAccessToFunds: true })` deploys an eSIM wallet, binds it and grants it access to the device wallet's tokens, and `eSIMWallet.buyDataBundleWithTransfer(...)` sends the tokens and buys in one go, without pull access. The contract surfaces (`deviceWallet`, `eSIMWallet`, `deviceWalletFactory`, `eSIMWalletFactory`, `registry`, `paymentAdapter`, `P256Verifier`) are only diff --git a/docs/README.md b/docs/README.md index 44a6b81..9160111 100644 --- a/docs/README.md +++ b/docs/README.md @@ -64,3 +64,20 @@ Every method entry follows the same shape: A write (anything that changes state) either sends a user operation (mobile) or a transaction (admin) and resolves to a hash. A read is a plain `view` call and resolves to the value itself. + +A write the contract would refuse throws `ContractRevertError` before anything is sent, with the contract's error name in `decoded.errorName`: + +```ts +import { ContractRevertError } from "kokio-sdk"; + +try { + await kokio.eSIMWallet!.buyDataBundleWithToken(dataBundleDetails, asset, maxAmountIn, paymentReference); +} catch (err) { + if (err instanceof ContractRevertError && err.decoded?.errorName === "PaymentReferenceAlreadyUsed") { + // this order was already paid for + } + throw err; +} +``` + +The backend's wallet client can hold a local private key (`privateKeyToAccount`) or a connected wallet. Admin writes sign with whichever account the client carries. diff --git a/docs/admin/device-wallet-factory.md b/docs/admin/device-wallet-factory.md index b327dc3..bf9b414 100644 --- a/docs/admin/device-wallet-factory.md +++ b/docs/admin/device-wallet-factory.md @@ -58,6 +58,8 @@ wallet is not registered until this runs. The salt has to match the one the deploy used: the factory recomputes the wallet's address from it to check the wallet is real. +The same applies when the wallet was deployed by its first sponsored user operation: until this runs, the device wallet cannot deploy eSIM wallets. On a hosted RPC, wait a few confirmations before telling the app to go ahead. A bundler that simulates against a node one block behind will still see the wallet as unregistered. + ```ts const hash = await admin.deviceWalletFactory.postCreateAccount( deviceWalletAddress, deviceUniqueIdentifier, ownerKey, salt, diff --git a/docs/mobile/device-wallet.md b/docs/mobile/device-wallet.md index b5fad90..5d85e09 100644 --- a/docs/mobile/device-wallet.md +++ b/docs/mobile/device-wallet.md @@ -14,8 +14,7 @@ const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash }); if (!receipt.success) throw new Error("operation reverted"); ``` -An operation whose calls revert is still mined and still returns a receipt, -so check `success` rather than treating a resolved await as confirmation. +A call that would revert is caught before sending: the write throws `ContractRevertError` with the contract's error name in `decoded.errorName`. If the chain changes between that check and inclusion, the operation can still revert on chain. It is then mined and returns a receipt, so check `success` rather than treating a resolved await as confirmation. ## sendUserOperation @@ -33,6 +32,22 @@ const hash = await kokio.deviceWallet!.sendUserOperation([ Returns: `Promise`, the user operation hash. +## deployAndBindESIMWallet + +Deploys a new eSIM wallet for this device wallet and adds it to the device wallet's list, in one user operation and one passkey prompt. Use it when a user adds a new eSIM. Pass `grantAccessToFunds: true` to also let the new eSIM wallet pull tokens from this device wallet, which `buyDataBundleWithToken` needs when the eSIM wallet holds less than the price. + +The device wallet must already be registered by the backend (`admin.deviceWalletFactory.postCreateAccount`), or the deploy reverts. Each salt gives one address, so use a new salt for each eSIM wallet on the same device. + +```ts +const { userOpHash, eSIMWalletAddress } = await kokio.deviceWallet!.deployAndBindESIMWallet( + 1n, // salt + { grantAccessToFunds: true }, +); +kokio.setESIMWalletAddress(eSIMWalletAddress); +``` + +Returns: `Promise<{ userOpHash: Hash; eSIMWalletAddress: Address }>`. The address is known before the operation lands, so wait for the receipt before reading from it. + ## addESIMWallet Adds an eSIM wallet this device already owns onto the device wallet's list. diff --git a/docs/mobile/esim-wallet-factory.md b/docs/mobile/esim-wallet-factory.md index b3a6fac..69fb844 100644 --- a/docs/mobile/esim-wallet-factory.md +++ b/docs/mobile/esim-wallet-factory.md @@ -2,17 +2,26 @@ `kokio.eSIMWalletFactory` -Deploys a new eSIM wallet for a device wallet. Present as soon as `Kokio` has +Predicts and deploys eSIM wallets for a device wallet. Present as soon as `Kokio` has a `smartAccountClient`, chain-wide like the device wallet factory. +To deploy a new eSIM wallet, use [`deviceWallet.deployAndBindESIMWallet`](device-wallet.md#deployandbindesimwallet). It deploys and binds in one user operation and returns the new address. + +## getCounterFactualAddress + +Works out the address an eSIM wallet will have for a device wallet and salt, before it is deployed. A plain read, no user operation. + ```ts -const hash = await kokio.eSIMWalletFactory!.deployESIMWalletWithUserOp(deviceWalletAddress, salt); +const eSIMWalletAddress = await kokio.eSIMWalletFactory!.getCounterFactualAddress(deviceWalletAddress, 1n); ``` +Returns: `Promise
`. + ## deployESIMWalletWithUserOp -Deploys a new eSIM wallet, owned by the given device wallet. Use it when a -user is adding a new eSIM to a device wallet they already have. The device +**Deprecated.** Use `deviceWallet.deployAndBindESIMWallet`. This deploys the eSIM wallet without adding it to the device wallet's list, so the device wallet does not treat it as its own until `addESIMWallet` runs. + +Deploys a new eSIM wallet, owned by the given device wallet. The device wallet sending the user operation has to be a wallet the registry recognizes. ```ts diff --git a/docs/mobile/esim-wallet.md b/docs/mobile/esim-wallet.md index 87f00b2..1695556 100644 --- a/docs/mobile/esim-wallet.md +++ b/docs/mobile/esim-wallet.md @@ -20,9 +20,11 @@ const hash = await kokio.eSIMWallet!.buyDataBundleWithToken(dataBundleDetails, a ## buyDataBundleWithToken Buys a data bundle for this eSIM, paid for in an ERC-20 the payment adapter -accepts (USDC on Base Sepolia today). Use this for the everyday purchase +accepts (`USDC` and `USDCt` on Base Sepolia today). Use this for the everyday purchase flow. +If this eSIM wallet holds less than the price, the contract pulls the rest from the device wallet. That needs `deviceWallet.toggleAccessToFunds(eSIMWalletAddress, true)` first, otherwise the purchase reverts with `FundsAccessRevoked`. Without that access, use `buyDataBundleWithTransfer`. + Check `priceCapUSDCents()` first: a price above the cap reverts. Read `kokio.paymentAdapter!.quote(asset, priceUSDCents)` to size `maxAmountIn` - the most of `asset` this purchase may spend, in its smallest unit. Nothing @@ -49,6 +51,20 @@ const hash = await kokio.eSIMWallet!.buyDataBundleWithToken( Returns: `Promise`, a user operation hash. +## buyDataBundleWithTransfer + +The same purchase as `buyDataBundleWithToken`, for when the eSIM wallet has no access to the device wallet's funds. In one user operation the device wallet sends the eSIM wallet whatever it is short of the quote, then the purchase runs. Arguments are the same. + +The device wallet must hold enough of the asset's token. It sends only the shortfall, so tokens already on the eSIM wallet are used first. + +```ts +const hash = await kokio.eSIMWallet!.buyDataBundleWithTransfer( + dataBundleDetails, asset, maxAmountIn, paymentReference, +); +``` + +Returns: `Promise`, a user operation hash. + ## sendTokenToDeviceWallet Sends an ERC-20 held by this eSIM wallet back to its owning device wallet. diff --git a/docs/mobile/smart-account.md b/docs/mobile/smart-account.md index 52c5389..1f68d63 100644 --- a/docs/mobile/smart-account.md +++ b/docs/mobile/smart-account.md @@ -33,6 +33,8 @@ const account = await kokio.smartAccount.getSmartWallet( Returns: `KokioSmartAccount`, a viem smart account object. Pass it to `getSmartWalletClient`. +The wallet client given to `Kokio` does not need an `account`. The passkey signs, so a client with just a chain and transport is enough. + ## getSmartWalletClient Builds the client that signs with the passkey and sends user operations @@ -47,3 +49,15 @@ Returns: `KokioSmartAccountClient`, a bundler client that can also read contracts directly (it carries viem's public actions too). Pass it as `smartAccountClient` to a new `Kokio(...)` call so the contract surfaces (`deviceWallet`, `eSIMWallet`, and the rest) become available. + +Gas is sponsored by the paymaster at the same endpoint. The gas policy id given to `Kokio` is optional. Pass `""` to send no policy, or a Pimlico sponsorship policy id to have that policy's rules applied. + +To send user operations somewhere other than Pimlico, such as a local bundler in tests, pass `bundlerUrl`. That endpoint must also answer the ERC-7677 paymaster methods. + +```ts +const smartAccountClient = await kokio.smartAccount.getSmartWalletClient(account, { + bundlerUrl: "http://127.0.0.1:4337", +}); +``` + +If a user operation would revert, sending it throws `ContractRevertError` with the contract's error name in `decoded.errorName`, and nothing is sent. diff --git a/package-lock.json b/package-lock.json index 6f7266e..93981ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,26 +1,36 @@ { "name": "kokio-sdk", - "version": "3.0.2", + "version": "3.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "kokio-sdk", - "version": "3.0.2", + "version": "3.1.0", "license": "MIT", "dependencies": { "@noble/curves": "2.3.0", - "@peculiar/asn1-ecc": "2.9.3", - "@peculiar/asn1-schema": "2.9.3", - "@simplewebauthn/server": "13.3.2", - "react-native-passkey": "3.6.1", + "@scure/base": "1.2.6", "viem": "2.55.19" }, "devDependencies": { + "@pimlico/alto": "0.0.21", + "@pimlico/mock-paymaster": "0.0.8", + "@simplewebauthn/server": "13.3.2", "@types/node": "22.20.1", "dotenv": "17.4.2", + "prool": "0.0.25", + "react-native-passkey": "3.6.1", "typescript": "5.9.3", "vitest": "4.1.11" + }, + "peerDependencies": { + "react-native-passkey": "^3.6.1" + }, + "peerDependenciesMeta": { + "react-native-passkey": { + "optional": true + } } }, "node_modules/@adraffy/ens-normalize": { @@ -29,12 +39,128 @@ "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", "license": "MIT" }, + "node_modules/@fastify/ajv-compiler": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz", + "integrity": "sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "fast-uri": "^2.0.0" + } + }, + "node_modules/@fastify/cors": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-8.4.2.tgz", + "integrity": "sha512-IVynbcPG9eWiJ0P/A1B+KynmiU/yTYbu3ooBUSIeHfca/N1XLb9nIJVCws+YTr2q63MA8Y6QLeXQczEv4npM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fastify-plugin": "^4.0.0", + "mnemonist": "0.39.5" + } + }, + "node_modules/@fastify/error": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.4.1.tgz", + "integrity": "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", + "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stringify": "^5.7.0" + } + }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", + "integrity": "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, + "node_modules/@fastify/websocket": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@fastify/websocket/-/websocket-10.0.1.tgz", + "integrity": "sha512-8/pQIxTPRD8U94aILTeJ+2O3el/r19+Ej5z1O1mXlqplsUH7KzCjAI0sgd5DM/NoPjAi5qLFNIjgM5+9/rGSNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexify": "^4.1.2", + "fastify-plugin": "^4.0.0", + "ws": "^8.0.0" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.5.tgz", + "integrity": "sha512-7VZM+SVdEcUUqSQeNI3zM8Qs/BhQKZndPo2h5VkYkAM8Iz0wJIa8mKV5ekQGqG8UUsnkQ0NMxIxwkIHYvj0qOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz", + "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.5.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@hexagon/base64": { "version": "1.1.28", "resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz", "integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ioredis/commands": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.10.0.tgz", + "integrity": "sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==", + "dev": true, "license": "MIT" }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.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", @@ -42,12 +168,108 @@ "dev": true, "license": "MIT" }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/@levischuck/tiny-cbor": { "version": "0.2.11", "resolved": "https://registry.npmjs.org/@levischuck/tiny-cbor/-/tiny-cbor-0.2.11.tgz", "integrity": "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==", + "dev": true, "license": "MIT" }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", + "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz", + "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz", + "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz", + "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz", + "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz", + "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@noble/ciphers": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", @@ -87,1169 +309,5538 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@oxc-project/types": { - "version": "0.146.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.146.0.tgz", - "integrity": "sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==", + "node_modules/@opentelemetry/api": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" } }, - "node_modules/@peculiar/asn1-android": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-android/-/asn1-android-2.9.3.tgz", - "integrity": "sha512-hiRJvr5ydif9fbTA7czZw1OfgzYDhu5gXNzhDfS3wSXzWYoSS/BHY+Wu2c36CNbn3mI6FoVLf0yHvQy0D4rZWw==", - "license": "MIT", + "node_modules/@opentelemetry/api-logs": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.52.1.tgz", + "integrity": "sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/asn1-schema": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@peculiar/asn1-cms": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.9.3.tgz", - "integrity": "sha512-N3POfw5RA7efAliAATiudtmvKQqukVEOzrMQuqQY/us2EPKczMy2WiecLt1SX6s3b0OwcFaPUXGF6uIYlBUTbg==", - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.9.3", - "@peculiar/asn1-x509": "^2.9.3", - "@peculiar/asn1-x509-attr": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.25.1.tgz", + "integrity": "sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@peculiar/asn1-csr": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.9.3.tgz", - "integrity": "sha512-E9zYmC5mk7eiDKqQAOsZGrJ7mUCIDC0031s4Nsl7dj1Za5EBKcHVqY+1vD/a4xbk480PGqvi455W2b4FeHRJ8Q==", - "license": "MIT", + "node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/asn1-schema": "^2.9.3", - "@peculiar/asn1-x509": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@peculiar/asn1-ecc": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.9.3.tgz", - "integrity": "sha512-4xmeZiZ46VI2qGbiZPzdv6p9IhMtjWdbwZf3VCgN8OAVcued60ej5Ki2FF94srVH4Ot/h45Co7T5C/fpQXP4rA==", - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.9.3", - "@peculiar/asn1-x509": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" } }, - "node_modules/@peculiar/asn1-pfx": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.9.3.tgz", - "integrity": "sha512-Nzwoj+fRr1XB9CQuc4AanUuvQ3OIXAY+ngZIYP+eZUqd+Sonj+ZHTnrg+egQuUJ64/iMi9HFPN04MokGrFTK0w==", - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.52.1.tgz", + "integrity": "sha512-pVkSH20crBwMTqB3nIN4jpQKUEoB0Z94drIHpYyEqs7UBr+I0cpYyOR3bqjA/UasQUMROb3GX8ZX4/9cVRqGBQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/asn1-cms": "^2.9.3", - "@peculiar/asn1-pkcs8": "^2.9.3", - "@peculiar/asn1-rsa": "^2.9.3", - "@peculiar/asn1-schema": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-grpc-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" } }, - "node_modules/@peculiar/asn1-pkcs8": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.9.3.tgz", - "integrity": "sha512-ecGZpkY6Lq5bSgTFU+LS74WjawzDgjWHcjFMVNPH/1C0j53Xi9dmLcPMdmZyk8gdsd2RKeV1fP9EbLB6W6zZ1g==", - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/asn1-schema": "^2.9.3", - "@peculiar/asn1-x509": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@peculiar/asn1-pkcs9": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.9.3.tgz", - "integrity": "sha512-yjWVrQEmPp2y9lWjLLE28BRHbt7wYdwWvwXjFgNuekP9mDD/ofz31muVI8qOg2as7XZs1bZIZGPPnJ/0osTClQ==", - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz", + "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/asn1-cms": "^2.9.3", - "@peculiar/asn1-pfx": "^2.9.3", - "@peculiar/asn1-pkcs8": "^2.9.3", - "@peculiar/asn1-schema": "^2.9.3", - "@peculiar/asn1-x509": "^2.9.3", - "@peculiar/asn1-x509-attr": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@peculiar/asn1-rsa": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.9.3.tgz", - "integrity": "sha512-t7m3e9p/Gf9YoMM+hLsHUqB+NhOlifiOkENAIG4RV2BFWVGTATVzbXoR8L0EgNWpiriPaeIjBCS5B9PTtkaxQw==", - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.9.3", - "@peculiar/asn1-x509": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" } }, - "node_modules/@peculiar/asn1-schema": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.9.3.tgz", - "integrity": "sha512-SOux4+jikCnOwoJvpBp/grOqzFmJPnNSwe3sAg1Bn93YdmCiDtvolZifJIhiRq0UWMTnLRPj9/ZCMAc2W9VsMQ==", - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.52.1.tgz", + "integrity": "sha512-05HcNizx0BxcFKKnS5rwOV+2GevLTVIRA0tRgWYyw4yCgR53Ic/xk83toYKts7kbzcI+dswInUg/4s8oyA+tqg==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/utils": "^2.0.2", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" } }, - "node_modules/@peculiar/asn1-x509": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.9.3.tgz", - "integrity": "sha512-HE+ejy9dX9JP3yLL6CGYoWym4Cted1lGXH7DxsbNDGiq8KabwVR7mzYidwsyNZ/m0hNWjiS+dzSwrsgMB/OIaQ==", - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/asn1-schema": "^2.9.3", - "@peculiar/utils": "^2.0.2", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@peculiar/asn1-x509-attr": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.9.3.tgz", - "integrity": "sha512-v5Oa6p7hCT3ONqYHQyTFQYcycD06eMhHbr0m7evpvPQSpWJIq8GgbdnvA9bVGTUlOx6KOeDrX7Z0W4s/yboNTg==", - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz", + "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/asn1-schema": "^2.9.3", - "@peculiar/asn1-x509": "^2.9.3", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@peculiar/utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", - "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", - "license": "MIT", - "dependencies": { - "tslib": "^2.8.1" + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" } }, - "node_modules/@peculiar/x509": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", - "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-proto": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.52.1.tgz", + "integrity": "sha512-pt6uX0noTQReHXNeEslQv7x311/F1gJzMnp1HD2qgypLRPbXDeMzzeTngRTUaUbP6hqWNtPxuLr4DEoZG+TcEQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@peculiar/asn1-cms": "^2.6.0", - "@peculiar/asn1-csr": "^2.6.0", - "@peculiar/asn1-ecc": "^2.6.0", - "@peculiar/asn1-pkcs9": "^2.6.0", - "@peculiar/asn1-rsa": "^2.6.0", - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "pvtsutils": "^1.3.6", - "reflect-metadata": "^0.2.2", - "tslib": "^2.8.1", - "tsyringe": "^4.10.0" + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" } }, - "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.5.tgz", - "integrity": "sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==", - "cpu": [ - "arm" - ], + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.5.tgz", - "integrity": "sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz", + "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.5.tgz", - "integrity": "sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" } }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.5.tgz", - "integrity": "sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/exporter-zipkin": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.25.1.tgz", + "integrity": "sha512-RmOwSvkimg7ETwJbUOPTMhJm9A9bG1U8s7Zo3ajDh4zM7eYcycQ0dM7FbLD6NXWbI2yj7UY4q8BKinKYBQksyw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" } }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.5.tgz", - "integrity": "sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.5.tgz", - "integrity": "sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==", - "cpu": [ - "arm" - ], + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz", + "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.5.tgz", - "integrity": "sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" } }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.5.tgz", - "integrity": "sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/instrumentation": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.52.1.tgz", + "integrity": "sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.5.tgz", - "integrity": "sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==", - "cpu": [ - "ppc64" - ], + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.46.1.tgz", + "integrity": "sha512-AyXVnlCf/xV3K/rNumzKxZqsULyITJH6OVLiW6730JPRqWA7Zc9bvYoVNpN6iOpTU8CasH34SU/ksVJmObFibQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.5.tgz", - "integrity": "sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==", - "cpu": [ - "s390x" - ], + "node_modules/@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" } }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.5.tgz", - "integrity": "sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.5.tgz", - "integrity": "sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.43.1.tgz", + "integrity": "sha512-ht7YGWQuV5BopMcw5Q2hXn3I8eG8TH0J/kc/GMcW4CuNTgiP6wCu44BOnucJWL3CmFWaRHI//vWyAhaC8BwePw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.5.tgz", - "integrity": "sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" } }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.5.tgz", - "integrity": "sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.5.tgz", - "integrity": "sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.16.1.tgz", + "integrity": "sha512-K/qU4CjnzOpNkkKO4DfCLSQshejRNAJtd4esgigo/50nxCB6XCyi1dhAblUHM9jG5dRm8eu0FB+t87nIo99LYQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", - "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "node_modules/@opentelemetry/instrumentation-dataloader/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MIT" - }, - "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", + "license": "Apache-2.0", "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" + "@opentelemetry/api": "^1.3.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">=14" } }, - "node_modules/@scure/bip32/node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", - "license": "MIT", + "node_modules/@opentelemetry/instrumentation-dataloader/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@noble/hashes": "1.8.0" + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=14" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@scure/bip32/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", + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.47.1.tgz", + "integrity": "sha512-QNXPTWteDclR2B4pDFpz0TNghgB33UMjUt14B+BZPmtH1MwUFAfLHBaP5If0Z5NZC+jaH8oF2glgYjrmhZWmSw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=14" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "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", + "node_modules/@opentelemetry/instrumentation-express/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" + "@opentelemetry/api": "^1.3.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">=14" } }, - "node_modules/@scure/bip39/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", + "node_modules/@opentelemetry/instrumentation-express/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=14" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@simplewebauthn/server": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.3.2.tgz", - "integrity": "sha512-KEDhfcGP1PAKRVSDjA3npTQFqS2b/srm+ipoNBNHdkzrHAlaRQUTE+a5f4ywsx6thxAw1NU2rYcLEY1949RGbQ==", - "license": "MIT", + "node_modules/@opentelemetry/instrumentation-fastify": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.38.0.tgz", + "integrity": "sha512-HBVLpTSYpkQZ87/Df3N0gAw7VzYZV3n28THIBrJWfuqw3Or7UqdhnjeuMIPQ04BKk3aZc0cWn2naSQObbh5vXw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@hexagon/base64": "^1.1.27", - "@levischuck/tiny-cbor": "^0.2.2", - "@peculiar/asn1-android": "^2.6.0", - "@peculiar/asn1-ecc": "^2.6.1", - "@peculiar/asn1-rsa": "^2.6.1", - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "@peculiar/x509": "^1.14.3" + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.52.0", + "@opentelemetry/semantic-conventions": "^1.22.0" }, "engines": { - "node": ">=20.0.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.19.1.tgz", + "integrity": "sha512-6g0FhB3B9UobAR60BGTcXg4IHZ6aaYJzp0Ki5FhnxyAPt8Ns+9SSvgcrnsN2eGmk3RWG5vYycUGOEApycQL24A==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "node_modules/@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "node_modules/@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } }, - "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.43.1.tgz", + "integrity": "sha512-M6qGYsp1cURtvVLGDrPPZemMFEbuMmCXgQYTReC/IbimV5sGrLBjB+/hANUpRZjX67nGLdKSVLZuQQAiNz+sww==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } }, - "node_modules/@types/node": { - "version": "22.20.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", - "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", + "node_modules/@opentelemetry/instrumentation-generic-pool/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "undici-types": "~6.21.0" + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@vitest/expect": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", - "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", + "node_modules/@opentelemetry/instrumentation-generic-pool/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", - "chai": "^6.2.2", - "tinyrainbow": "^3.1.0" + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@vitest/mocker": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", - "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.47.1.tgz", + "integrity": "sha512-EGQRWMGqwiuVma8ZLAZnExQ7sBvbOx0N/AE/nlafISPs8S+QtXX+Viy6dcQwVWwYHQPAcuY3bFt3xgoAwb4ZNQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@vitest/spy": "4.1.11", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" + "@opentelemetry/instrumentation": "^0.57.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=14" }, "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@vitest/pretty-format": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", - "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", + "node_modules/@opentelemetry/instrumentation-graphql/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "tinyrainbow": "^3.1.0" + "@opentelemetry/api": "^1.3.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=14" } }, - "node_modules/@vitest/runner": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", - "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", + "node_modules/@opentelemetry/instrumentation-graphql/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@vitest/utils": "4.1.11", - "pathe": "^2.0.3" + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@vitest/snapshot": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", - "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.45.2.tgz", + "integrity": "sha512-7Ehow/7Wp3aoyCrZwQpU7a2CnoMq0XhIcioFuKjBb0PLYfBfmTsFTUyatlHu0fRxhwcRsSQRTvEhmZu8CppBpQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@vitest/pretty-format": "4.1.11", - "@vitest/utils": "4.1.11", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@vitest/spy": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", - "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", + "node_modules/@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@vitest/utils": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", - "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", + "node_modules/@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@vitest/pretty-format": "4.1.11", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/abitype": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", - "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.52.1.tgz", + "integrity": "sha512-dG/aevWhaP+7OLv4BQQSEKMJv8GyeOp3Wxl31NHqE8xo9/fYMfEljiZphUHIfyg4gnZ9swMyWjfOQs5GUQe54Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/instrumentation": "0.52.1", + "@opentelemetry/semantic-conventions": "1.25.1", + "semver": "^7.5.2" }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3.22.0 || ^4.0.0" + "engines": { + "node": ">=14" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/asn1js": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", - "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", - "license": "BSD-3-Clause", + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "pvtsutils": "^1.3.6", - "pvutils": "^1.1.5", - "tslib": "^2.8.1" + "@opentelemetry/semantic-conventions": "1.25.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">=12" + "node": ">=14" } }, - "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.42.0.tgz", + "integrity": "sha512-P11H168EKvBB9TUSasNDOGJCSkpT44XgoM6d3gRIWAa9ghLpYhl0uRkS8//MqPzcJVHr3h3RmfXIpiYLjyIZTw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.52.0", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.23.0" + }, "engines": { - "node": ">=18" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "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==", + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.7.1.tgz", + "integrity": "sha512-OtjaKs8H7oysfErajdYr1yuWSjMAectT7Dwr+axIoZqT9lmEOkD/H/3rgAs8h/NIuEi2imSXD+vL4MZtOuJfqQ==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "node_modules/@opentelemetry/instrumentation-kafkajs/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, "engines": { - "node": ">=8" + "node": ">=14" } }, - "node_modules/dotenv": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", - "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "node_modules/@opentelemetry/instrumentation-kafkajs/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "license": "BSD-2-Clause", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, "engines": { - "node": ">=12" + "node": ">=14" }, - "funding": { - "url": "https://dotenvx.com" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/es-module-lexer": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", - "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.44.1.tgz", + "integrity": "sha512-U4dQxkNhvPexffjEmGwCq68FuftFK15JgUF05y/HlK3M6W/G2iEaACIfXdSnwVNe9Qh0sPfw8LbOPxrWzGWGMQ==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/@opentelemetry/instrumentation-knex/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@types/estree": "^1.0.0" + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" } }, - "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/expect-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", - "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "node_modules/@opentelemetry/instrumentation-knex/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, "engines": { - "node": ">=12.0.0" + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.47.1.tgz", + "integrity": "sha512-l/c+Z9F86cOiPJUllUCt09v+kICKvT+Vg1vOAJHtHPsJIzurGayucfCMq2acd/A/yxeNWunl9d9eqZ0G+XiI6A==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, "engines": { - "node": ">=12.0.0" + "node": ">=14" }, "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "@opentelemetry/api": "^1.3.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/@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=14" } }, - "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", + "node_modules/@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, "peerDependencies": { - "ws": "*" + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", - "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.44.1.tgz", + "integrity": "sha512-5MPkYCvG2yw7WONEjYj5lr5JFehTobW7wX+ZUFy81oF2lr9IPfZk9qO+FTaM0bGEiymwfLwKe6jE15nHn1nmHg==", "dev": true, - "license": "MPL-2.0", + "license": "Apache-2.0", "dependencies": { - "detect-libc": "^2.0.3" + "@opentelemetry/instrumentation": "^0.57.1" }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.33.0", - "lightningcss-darwin-arm64": "1.33.0", - "lightningcss-darwin-x64": "1.33.0", - "lightningcss-freebsd-x64": "1.33.0", - "lightningcss-linux-arm-gnueabihf": "1.33.0", - "lightningcss-linux-arm64-gnu": "1.33.0", - "lightningcss-linux-arm64-musl": "1.33.0", - "lightningcss-linux-x64-gnu": "1.33.0", - "lightningcss-linux-x64-musl": "1.33.0", - "lightningcss-win32-arm64-msvc": "1.33.0", - "lightningcss-win32-x64-msvc": "1.33.0" + "engines": { + "node": ">=14" } }, - "node_modules/lightningcss-android-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", - "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/instrumentation-lru-memoizer/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", - "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.52.0.tgz", + "integrity": "sha512-1xmAqOtRUQGR7QfJFfGV/M2kC7wmI2WgZdpru8hJl3S0r4hW0n3OQpEHlSGXJAaNFyvT+ilnwkT+g5L4ljHR6g==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", - "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", - "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.46.1.tgz", + "integrity": "sha512-3kINtW1LUTPkiXFRSSBmva1SXzS/72we/jL22N+BnF3DFcoewkdkHPYOIdAAk9gSicJ4d5Ojtt1/HeibEc5OQg==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", - "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", - "cpu": [ - "arm" - ], + "node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", - "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.45.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.45.1.tgz", + "integrity": "sha512-TKp4hQ8iKQsY7vnp/j0yJJ4ZsP109Ht6l4RHTj0lNEG1TfgTrIH5vJMbgmoYXWzNHAqBH2e7fncN12p3BP8LFg==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/mysql": "2.15.26" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", - "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", - "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.45.2.tgz", + "integrity": "sha512-h6Ad60FjCYdJZ5DTz1Lk2VmQsShiViKe0G7sYikb0GHI0NVvApp2XQNRHNjEMz87roFttGPLHOYVPlfy+yVIhQ==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", - "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", - "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.51.1.tgz", + "integrity": "sha512-QxgjSrxyWZc7Vk+qGSfsejPVFL1AgAJdSBMYZdDUbwg730D09ub3PXScB9d04vIqPriZ+0dqzjmQx0yWKiCi2Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.26.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1", + "@types/pg": "8.6.1", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pino": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pino/-/instrumentation-pino-0.41.0.tgz", + "integrity": "sha512-Kpv0fJRk/8iMzMk5Ue5BsUJfHkBJ2wQoIi/qduU1a1Wjx9GLj6J2G17PHjPK5mnZjPNzkFOXFADZMfgDioliQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.52.0", + "@opentelemetry/core": "^1.25.0", + "@opentelemetry/instrumentation": "^0.52.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis-4": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.46.1.tgz", + "integrity": "sha512-UMqleEoabYMsWoTkqyt9WAzXwZ4BlFZHO40wr3d5ZvtjKCHlD4YXLm+6OLCeIi/HkX7EXvQaz8gtAwkwwSEvcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis-4/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-redis-4/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.18.1.tgz", + "integrity": "sha512-5Cuy/nj0HBaH+ZJ4leuD7RjgvA844aY2WW+B5uLcWtxGjRZl3MNLuxnNg5DYWZNPO+NafSSnra0q49KWAHsKBg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.4.0.tgz", + "integrity": "sha512-UdMQBpz11SqtWlmDnk5SoqF5QDom4VmW8SVDt9Q2xuMWVh8lc0kVROfoo2pl7zU6H6gFR8eudb3eFXIdrFn0ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.52.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.52.1.tgz", + "integrity": "sha512-z175NXOtX5ihdlshtYBe5RpGeBoTXVCKPPLiQlD6FHvpM4Ch+p2B0yWKYSrBfLH24H9zjJiBdTrtD+hLlfnXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-transformer": "0.52.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.52.1.tgz", + "integrity": "sha512-zo/YrSDmKMjG+vPeA9aBBrsQM9Q/f2zo6N04WMB3yNldJRsgpRBeLLwvAt/Ba7dpehDLOEFBd1i2JCoaFtpCoQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/otlp-exporter-base": "0.52.1", + "@opentelemetry/otlp-transformer": "0.52.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.52.1.tgz", + "integrity": "sha512-I88uCZSZZtVa0XniRqQWKbjAUm73I8tpEy/uJYPPYw5d7BRdVk0RfTBQw8kSUl01oVWEuqxLDa802222MYyWHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-logs": "0.52.1", + "@opentelemetry/sdk-metrics": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "protobufjs": "^7.3.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz", + "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.25.1.tgz", + "integrity": "sha512-p6HFscpjrv7//kE+7L+3Vn00VEDUJB0n6ZrjkTYHrJ58QZ8B3ajSJhRbCcY6guQ3PDjTbxWklyvIN2ojVbIb1A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.25.1.tgz", + "integrity": "sha512-nBprRf0+jlgxks78G/xq72PipVK+4or9Ypntw0gVZYNTCSK8rg5SeaGV19tV920CMqBD/9UIOiFr23Li/Q8tiA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz", + "integrity": "sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.25.1.tgz", + "integrity": "sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.52.1.tgz", + "integrity": "sha512-MBYh+WcPPsN8YpRHRmK1Hsca9pVlyyKd4BxOC4SsgHACnl/bPp4Cri9hWhVm5+2tiQ9Zf4qSc1Jshw9tOLGWQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.25.1.tgz", + "integrity": "sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-node": { + "version": "0.52.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.52.1.tgz", + "integrity": "sha512-uEG+gtEr6eKd8CVWeKMhH2olcCHM9dEK68pe0qE0be32BcCRsvYURhHaD1Srngh1SQcnQzZ4TP324euxqtBOJA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.52.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/exporter-trace-otlp-grpc": "0.52.1", + "@opentelemetry/exporter-trace-otlp-http": "0.52.1", + "@opentelemetry/exporter-trace-otlp-proto": "0.52.1", + "@opentelemetry/exporter-zipkin": "1.25.1", + "@opentelemetry/instrumentation": "0.52.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/sdk-logs": "0.52.1", + "@opentelemetry/sdk-metrics": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "@opentelemetry/sdk-trace-node": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz", + "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.25.1.tgz", + "integrity": "sha512-nMcjFIKxnFqoez4gUmihdBrbpsEnAX/Xj16sGvZm+guceYE0NE00vLhpDVK6f3q8Q4VFI5xG8JjlXKMB/SkTTQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "1.25.1", + "@opentelemetry/core": "1.25.1", + "@opentelemetry/propagator-b3": "1.25.1", + "@opentelemetry/propagator-jaeger": "1.25.1", + "@opentelemetry/sdk-trace-base": "1.25.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz", + "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz", + "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.25.1", + "@opentelemetry/resources": "1.25.1", + "@opentelemetry/semantic-conventions": "1.25.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz", + "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", + "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.40.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.1.tgz", + "integrity": "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.146.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.146.0.tgz", + "integrity": "sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@peculiar/asn1-android": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-android/-/asn1-android-2.9.3.tgz", + "integrity": "sha512-hiRJvr5ydif9fbTA7czZw1OfgzYDhu5gXNzhDfS3wSXzWYoSS/BHY+Wu2c36CNbn3mI6FoVLf0yHvQy0D4rZWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.9.3.tgz", + "integrity": "sha512-N3POfw5RA7efAliAATiudtmvKQqukVEOzrMQuqQY/us2EPKczMy2WiecLt1SX6s3b0OwcFaPUXGF6uIYlBUTbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.3", + "@peculiar/asn1-x509": "^2.9.3", + "@peculiar/asn1-x509-attr": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.9.3.tgz", + "integrity": "sha512-E9zYmC5mk7eiDKqQAOsZGrJ7mUCIDC0031s4Nsl7dj1Za5EBKcHVqY+1vD/a4xbk480PGqvi455W2b4FeHRJ8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.3", + "@peculiar/asn1-x509": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-ecc": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.9.3.tgz", + "integrity": "sha512-4xmeZiZ46VI2qGbiZPzdv6p9IhMtjWdbwZf3VCgN8OAVcued60ej5Ki2FF94srVH4Ot/h45Co7T5C/fpQXP4rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.3", + "@peculiar/asn1-x509": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.9.3.tgz", + "integrity": "sha512-Nzwoj+fRr1XB9CQuc4AanUuvQ3OIXAY+ngZIYP+eZUqd+Sonj+ZHTnrg+egQuUJ64/iMi9HFPN04MokGrFTK0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.9.3", + "@peculiar/asn1-pkcs8": "^2.9.3", + "@peculiar/asn1-rsa": "^2.9.3", + "@peculiar/asn1-schema": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.9.3.tgz", + "integrity": "sha512-ecGZpkY6Lq5bSgTFU+LS74WjawzDgjWHcjFMVNPH/1C0j53Xi9dmLcPMdmZyk8gdsd2RKeV1fP9EbLB6W6zZ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.3", + "@peculiar/asn1-x509": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.9.3.tgz", + "integrity": "sha512-yjWVrQEmPp2y9lWjLLE28BRHbt7wYdwWvwXjFgNuekP9mDD/ofz31muVI8qOg2as7XZs1bZIZGPPnJ/0osTClQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.9.3", + "@peculiar/asn1-pfx": "^2.9.3", + "@peculiar/asn1-pkcs8": "^2.9.3", + "@peculiar/asn1-schema": "^2.9.3", + "@peculiar/asn1-x509": "^2.9.3", + "@peculiar/asn1-x509-attr": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.9.3.tgz", + "integrity": "sha512-t7m3e9p/Gf9YoMM+hLsHUqB+NhOlifiOkENAIG4RV2BFWVGTATVzbXoR8L0EgNWpiriPaeIjBCS5B9PTtkaxQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.3", + "@peculiar/asn1-x509": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.9.3.tgz", + "integrity": "sha512-SOux4+jikCnOwoJvpBp/grOqzFmJPnNSwe3sAg1Bn93YdmCiDtvolZifJIhiRq0UWMTnLRPj9/ZCMAc2W9VsMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.9.3.tgz", + "integrity": "sha512-HE+ejy9dX9JP3yLL6CGYoWym4Cted1lGXH7DxsbNDGiq8KabwVR7mzYidwsyNZ/m0hNWjiS+dzSwrsgMB/OIaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.3", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.9.3.tgz", + "integrity": "sha512-v5Oa6p7hCT3ONqYHQyTFQYcycD06eMhHbr0m7evpvPQSpWJIq8GgbdnvA9bVGTUlOx6KOeDrX7Z0W4s/yboNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.3", + "@peculiar/asn1-x509": "^2.9.3", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", + "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@pimlico/alto": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/@pimlico/alto/-/alto-0.0.21.tgz", + "integrity": "sha512-gLLGv56odFtd9z8Jo3yDK2ykjLsxOUqsICS8lV90C0VMVx/jSbC4lykbl5tg0tw+0g1CaxfaRjfkfGFbzNf63A==", + "dev": true, + "license": "GPL-3.0-or-later", + "dependencies": { + "@fastify/cors": "8.4.2", + "@fastify/websocket": "^10.0.1", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/core": "^1.25.1", + "@opentelemetry/exporter-trace-otlp-proto": "^0.52.1", + "@opentelemetry/instrumentation-fastify": "^0.38.0", + "@opentelemetry/instrumentation-http": "^0.52.1", + "@opentelemetry/instrumentation-ioredis": "^0.42.0", + "@opentelemetry/instrumentation-pino": "^0.41.0", + "@opentelemetry/instrumentation-undici": "^0.4.0", + "@opentelemetry/sdk-node": "^0.52.1", + "@opentelemetry/sdk-trace-base": "^1.25.1", + "@opentelemetry/semantic-conventions": "^1.25.1", + "@pimlico/opentelemetry-instrumentation-viem": "^0.0.4", + "@sentry/node": "^9.15.0", + "@types/bull": "^4.10.4", + "@types/node": "^18.16.3", + "@types/ws": "^8.5.10", + "abitype": "^0.8.0", + "async-mutex": "^0.4.0", + "bull": "^4.15.1", + "dotenv": "^16.0.3", + "fastify": "^4.25.2", + "import-in-the-middle": "^1.14.2", + "ioredis": "^5.4.1", + "opentelemetry-instrumentation-fetch-node": "^1.2.3", + "pino": "^8.15.0", + "pino-http": "^8.4.0", + "pino-pretty": "^10.0.0", + "prom-client": "^14.2.0", + "type-fest": "^4.35.0", + "viem": "^2.44.4", + "yargs": "^17.7.1", + "zod": "^3.21.4", + "zod-validation-error": "^1.3.0" + }, + "bin": { + "alto": "esm/cli/alto.js" + } + }, + "node_modules/@pimlico/alto/node_modules/@types/node": { + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@pimlico/alto/node_modules/abitype": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-0.8.11.tgz", + "integrity": "sha512-bM4v2dKvX08sZ9IU38IN5BKmN+ZkOSd2oI4a9f0ejHYZQYV6cDr7j+d95ga0z2XHG36Y4jzoG5Z7qDqxp7fi/A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.19.1" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@pimlico/alto/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/@pimlico/alto/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@pimlico/mock-paymaster": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@pimlico/mock-paymaster/-/mock-paymaster-0.0.8.tgz", + "integrity": "sha512-aCacradtQRW6+eXfdQG+ef9VrQLnHKPvOdb51IJm52JC+bB1v/HXTjPnZDEbVd+RVnw/bSOectOaql+CCOR6Lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@fastify/cors": "^8.5.0", + "fastify": "^4.28.1", + "zod": "^3.24.2", + "zod-validation-error": "^1.3.0" + }, + "peerDependencies": { + "prool": "^0.0.25", + "viem": "^2.44.4" + } + }, + "node_modules/@pimlico/mock-paymaster/node_modules/@fastify/cors": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-8.5.0.tgz", + "integrity": "sha512-/oZ1QSb02XjP0IK1U0IXktEsw/dUBTxJOW7IpIeO8c/tNalw/KjoNSJv1Sf6eqoBPO+TDGkifq6ynFK3v68HFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fastify-plugin": "^4.0.0", + "mnemonist": "0.39.6" + } + }, + "node_modules/@pimlico/mock-paymaster/node_modules/mnemonist": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.6.tgz", + "integrity": "sha512-A/0v5Z59y63US00cRSLiloEIw3t5G+MiKz4BhX21FI+YBJXBOGW0ohFxTxO08dsOYlzxo87T7vGfZKYp2bcAWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.1" + } + }, + "node_modules/@pimlico/opentelemetry-instrumentation-viem": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@pimlico/opentelemetry-instrumentation-viem/-/opentelemetry-instrumentation-viem-0.0.4.tgz", + "integrity": "sha512-FlFIXU7CVgfDAn0ay2JeV3F6mO7pLR6UgP/DZMx/gN7RZ/HV2rW+ibk1QmcKAF7NGPk5II8vYyu02irb0u158A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.200.0" + } + }, + "node_modules/@pimlico/opentelemetry-instrumentation-viem/node_modules/@opentelemetry/api-logs": { + "version": "0.200.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.200.0.tgz", + "integrity": "sha512-IKJBQxh91qJ+3ssRly5hYEJ8NDHu9oY/B1PXVSCWf7zytmYO9RNLB0Ox9XQ/fJ8m6gY6Q6NtBWlmXfaXt5Uc4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@pimlico/opentelemetry-instrumentation-viem/node_modules/@opentelemetry/instrumentation": { + "version": "0.200.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.200.0.tgz", + "integrity": "sha512-pmPlzfJd+vvgaZd/reMsC8RWgTXn2WY1OWT5RT42m3aOn5532TozwXNDhg1vzqJ+jnvmkREcdLr27ebJEQt0Jg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.200.0", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "shimmer": "^1.2.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@prisma/instrumentation": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-6.11.1.tgz", + "integrity": "sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.5.tgz", + "integrity": "sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.5.tgz", + "integrity": "sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.5.tgz", + "integrity": "sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.5.tgz", + "integrity": "sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.5.tgz", + "integrity": "sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.5.tgz", + "integrity": "sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.5.tgz", + "integrity": "sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.5.tgz", + "integrity": "sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.5.tgz", + "integrity": "sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.5.tgz", + "integrity": "sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.5.tgz", + "integrity": "sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.5.tgz", + "integrity": "sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.5.tgz", + "integrity": "sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.5.tgz", + "integrity": "sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.5.tgz", + "integrity": "sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "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/bip32/node_modules/@noble/curves": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/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/@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/@scure/bip39/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/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sentry/core": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.47.1.tgz", + "integrity": "sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-9.47.1.tgz", + "integrity": "sha512-CDbkasBz3fnWRKSFs6mmaRepM2pa+tbZkrqhPWifFfIkJDidtVW40p6OnquTvPXyPAszCnDZRnZT14xyvNmKPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1", + "@opentelemetry/core": "^1.30.1", + "@opentelemetry/instrumentation": "^0.57.2", + "@opentelemetry/instrumentation-amqplib": "^0.46.1", + "@opentelemetry/instrumentation-connect": "0.43.1", + "@opentelemetry/instrumentation-dataloader": "0.16.1", + "@opentelemetry/instrumentation-express": "0.47.1", + "@opentelemetry/instrumentation-fs": "0.19.1", + "@opentelemetry/instrumentation-generic-pool": "0.43.1", + "@opentelemetry/instrumentation-graphql": "0.47.1", + "@opentelemetry/instrumentation-hapi": "0.45.2", + "@opentelemetry/instrumentation-http": "0.57.2", + "@opentelemetry/instrumentation-ioredis": "0.47.1", + "@opentelemetry/instrumentation-kafkajs": "0.7.1", + "@opentelemetry/instrumentation-knex": "0.44.1", + "@opentelemetry/instrumentation-koa": "0.47.1", + "@opentelemetry/instrumentation-lru-memoizer": "0.44.1", + "@opentelemetry/instrumentation-mongodb": "0.52.0", + "@opentelemetry/instrumentation-mongoose": "0.46.1", + "@opentelemetry/instrumentation-mysql": "0.45.1", + "@opentelemetry/instrumentation-mysql2": "0.45.2", + "@opentelemetry/instrumentation-pg": "0.51.1", + "@opentelemetry/instrumentation-redis-4": "0.46.1", + "@opentelemetry/instrumentation-tedious": "0.18.1", + "@opentelemetry/instrumentation-undici": "0.10.1", + "@opentelemetry/resources": "^1.30.1", + "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@prisma/instrumentation": "6.11.1", + "@sentry/core": "9.47.1", + "@sentry/node-core": "9.47.1", + "@sentry/opentelemetry": "9.47.1", + "import-in-the-middle": "^1.14.2", + "minimatch": "^9.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node-core": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-9.47.1.tgz", + "integrity": "sha512-7TEOiCGkyShJ8CKtsri9lbgMCbB+qNts2Xq37itiMPN2m+lIukK3OX//L8DC5nfKYZlgikrefS63/vJtm669hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/core": "9.47.1", + "@sentry/opentelemetry": "9.47.1", + "import-in-the-middle": "^1.14.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0", + "@opentelemetry/core": "^1.30.1 || ^2.0.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.0.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/context-async-hooks": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz", + "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/instrumentation-http": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.57.2.tgz", + "integrity": "sha512-1Uz5iJ9ZAlFOiPuwYg29Bf7bJJc/GeoeJIFKJYQf67nTVKFe8RHbEtxgkOmK4UGZNHKXcpW4P8cWBYzBn1USpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/instrumentation": "0.57.2", + "@opentelemetry/semantic-conventions": "1.28.0", + "forwarded-parse": "2.1.2", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.47.1.tgz", + "integrity": "sha512-OtFGSN+kgk/aoKgdkKQnBsQFDiG8WdCxu+UrHr0bXScdAmtSzLSraLo7wFIb25RVHfRWvzI5kZomqJYEg/l1iA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.10.1.tgz", + "integrity": "sha512-rkOGikPEyRpMCmNu9AQuV5dtRlDmJp2dK5sw8roVshAGoB6hH/3QjDtRhdwd75SsJwgynWUNRUYe0wAkTo16tQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@sentry/node/node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@sentry/opentelemetry": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-9.47.1.tgz", + "integrity": "sha512-STtFpjF7lwzeoedDJV+5XA6P89BfmFwFftmHSGSe3UTI8z8IoiR5yB6X2vCjSPvXlfeOs13qCNNCEZyznxM8Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/core": "9.47.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0", + "@opentelemetry/core": "^1.30.1 || ^2.0.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + } + }, + "node_modules/@simplewebauthn/server": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.3.2.tgz", + "integrity": "sha512-KEDhfcGP1PAKRVSDjA3npTQFqS2b/srm+ipoNBNHdkzrHAlaRQUTE+a5f4ywsx6thxAw1NU2rYcLEY1949RGbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hexagon/base64": "^1.1.27", + "@levischuck/tiny-cbor": "^0.2.2", + "@peculiar/asn1-android": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.1", + "@peculiar/asn1-rsa": "^2.6.1", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.1", + "@peculiar/x509": "^1.14.3" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/bull": { + "version": "4.10.4", + "resolved": "https://registry.npmjs.org/@types/bull/-/bull-4.10.4.tgz", + "integrity": "sha512-A+8uxa5GbzKcS7kZ9Z1OcOeSyrvVmfHtZi3VIrH1Gws0G0sTknB2SRllxTaAYhycGn7+nC0Pb8VjxIyZiTM81A==", + "deprecated": "This is a stub types definition. bull provides its own type definitions, so you do not need this installed.", + "dev": true, + "license": "MIT", + "dependencies": { + "bull": "*" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mysql": { + "version": "2.15.26", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", + "integrity": "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, + "node_modules/@types/shimmer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", + "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", + "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", + "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.11", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", + "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", + "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.11", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", + "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.11", + "@vitest/utils": "4.1.11", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", + "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", + "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.11", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/abitype": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", + "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", + "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/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "deprecated": "package has been renamed to acorn-import-attributes", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv/node_modules/fast-uri": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", + "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "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/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/async-mutex": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.1.tgz", + "integrity": "sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/avvio": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.4.0.tgz", + "integrity": "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@fastify/error": "^3.3.0", + "fastq": "^1.17.1" + } + }, + "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/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/bintrees": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", + "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", + "integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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.2.1" + } + }, + "node_modules/bull": { + "version": "4.16.5", + "resolved": "https://registry.npmjs.org/bull/-/bull-4.16.5.tgz", + "integrity": "sha512-lDsx2BzkKe7gkCYiT5Acj02DpTwDznl/VNN7Psn7M3USPG7Vs/BaClZJJTAG+ufAR9++N1/NiUTdaFBWDIl5TQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cron-parser": "^4.9.0", + "get-port": "^5.1.1", + "ioredis": "^5.3.2", + "lodash": "^4.17.21", + "msgpackr": "^1.11.2", + "semver": "^7.5.2", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "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/cluster-key-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.1.tgz", + "integrity": "sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, + "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/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "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/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "deprecated": "v4 is no longer maintained, upgrade to v5", + "dev": true, + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "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/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "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/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "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/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "dev": true, + "license": "MIT" + }, + "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/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-content-type-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", + "integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-copy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.1.0.tgz", + "integrity": "sha512-IuCOCDFM1F/s4LtG7Bjr3yUUwPHybyhqN74xk2cMYoP51vVeErMy8+6HGFchi/+45lW8uzhs6lBeEqks2GWt6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stringify": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", + "integrity": "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@fastify/merge-json-schemas": "^0.1.0", + "ajv": "^8.10.0", + "ajv-formats": "^3.0.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^2.1.0", + "json-schema-ref-resolver": "^1.0.1", + "rfdc": "^1.2.0" + } + }, + "node_modules/fast-json-stringify/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/fast-uri": { + "version": "2.4.7", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.7.tgz", + "integrity": "sha512-b8mggfg2R+m2OAb3Z+2HcJxUgU+2cY1JQondBDyXLdrEKNPxd96MvnB5yWKZdupsuX6GdBaAZHZo9msHX/Bb7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastify": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.29.1.tgz", + "integrity": "sha512-m2kMNHIG92tSNWv+Z3UeTR9AWLLuo7KctC7mlFPtMEVrfjIhmQhkQnT9v15qA/BfVq3vvj134Y0jl9SBje3jXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/ajv-compiler": "^3.5.0", + "@fastify/error": "^3.4.0", + "@fastify/fast-json-stringify-compiler": "^4.3.0", + "abstract-logging": "^2.0.1", + "avvio": "^8.3.0", + "fast-content-type-parse": "^1.1.0", + "fast-json-stringify": "^5.8.0", + "find-my-way": "^8.0.0", + "light-my-request": "^5.11.0", + "pino": "^9.0.0", + "process-warning": "^3.0.0", + "proxy-addr": "^2.0.7", + "rfdc": "^1.3.0", + "secure-json-parse": "^2.7.0", + "semver": "^7.5.4", + "toad-cache": "^3.3.0" + } + }, + "node_modules/fastify-plugin": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", + "integrity": "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastify/node_modules/pino": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", + "integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/fastify/node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/fastify/node_modules/pino-std-serializers": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", + "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastify/node_modules/pino/node_modules/process-warning": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.1.0.tgz", + "integrity": "sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fastify/node_modules/sonic-boom": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/fastify/node_modules/thread-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.2.0.tgz", + "integrity": "sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/fastq": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-my-way": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.2.tgz", + "integrity": "sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^3.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "dev": true, + "license": "MIT" + }, + "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", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.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==", + "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", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "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, + "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/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "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": "ISC" + }, + "node_modules/ioredis": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.11.1.tgz", + "integrity": "sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ioredis/commands": "1.10.0", + "cluster-key-slot": "1.1.1", + "debug": "4.4.3", + "denque": "2.1.0", + "redis-errors": "1.2.0", + "redis-parser": "3.0.0", + "standard-as-callback": "2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-core-module": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.17.0.tgz", + "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/json-schema-ref-resolver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", + "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/light-my-request": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.14.0.tgz", + "integrity": "sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "cookie": "^0.7.0", + "process-warning": "^3.0.0", + "set-cookie-parser": "^2.4.1" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "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.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mnemonist": { + "version": "0.39.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.5.tgz", + "integrity": "sha512-FPUtkhtJ0efmEFGpU14x7jGbTB+s18LrzRL2KgoWz9YvcY3cPomz8tih01GbHwnGk/OmkOKfqd/RAQoc8Lm7DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.1" + } + }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.12.1.tgz", + "integrity": "sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", + "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" + } + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "dev": true, + "license": "MIT" + }, + "node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "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/opentelemetry-instrumentation-fetch-node": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/opentelemetry-instrumentation-fetch-node/-/opentelemetry-instrumentation-fetch-node-1.2.3.tgz", + "integrity": "sha512-Qb11T7KvoCevMaSeuamcLsAD+pZnavkhDnlVL0kRozfhl42dKG5Q3anUklAFKJZjY3twLR+BnRa6DlwwkIE/+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@opentelemetry/instrumentation": "^0.46.0", + "@opentelemetry/semantic-conventions": "^1.17.0" + }, + "engines": { + "node": ">18.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.6.0" + } + }, + "node_modules/opentelemetry-instrumentation-fetch-node/node_modules/@opentelemetry/instrumentation": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.46.0.tgz", + "integrity": "sha512-a9TijXZZbk0vI5TGLZl+0kxyFfrXHhX6Svtz7Pp2/VBlCSKrazuULEyoJQrOknJyFWNMEmbbJgOciHCCpQcisw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/opentelemetry-instrumentation-fetch-node/node_modules/import-in-the-middle": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.1.tgz", + "integrity": "sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-assertions": "^1.9.0", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/ox": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.34.tgz", + "integrity": "sha512-12seOIk7dv8eAoGQhcWaeKZxNz304IVcDvb9U5Y7JZAEVe21Nm1YMxLjhWah+su5BD4Omx4Zz0z5x3ij9M4GYQ==", + "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.2.3", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/ox/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/ox/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/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.0.tgz", + "integrity": "sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "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": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.21.0.tgz", + "integrity": "sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^3.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.6.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-http": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/pino-http/-/pino-http-8.6.1.tgz", + "integrity": "sha512-J0hiJgUExtBXP2BjrK4VB305tHXS31sCmWJ9XJo2wPkLHa1NFPuW4V9wjG27PAc2fmBCigiNhQKpvrx+kntBPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-caller-file": "^2.0.5", + "pino": "^8.17.1", + "pino-std-serializers": "^6.2.2", + "process-warning": "^3.0.0" + } + }, + "node_modules/pino-pretty": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz", + "integrity": "sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.0", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss": { + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.17", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], + "license": "MIT", "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=0.10.0" } }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", - "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", - "cpu": [ - "x64" - ], + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], + "license": "MIT", "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=0.10.0" } }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/nanoid": { - "version": "3.3.18", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", - "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "node_modules/pretty-ms": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.1.tgz", + "integrity": "sha512-HzMy3Geq23nVALD/M2LliU+F+M+gVNsvkQWWqeBZ8HDiCgzo6YPJ/Omrmtq24EFrIsk0a3EkQGEd7bDOo+IhGA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "parse-ms": "^4.0.0" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/obug": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", - "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, - "funding": [ - "https://github.com/sponsors/sxzz", - "https://opencollective.com/debug" - ], "license": "MIT", "engines": { - "node": ">=12.20.0" + "node": ">= 0.6.0" } }, - "node_modules/ox": { - "version": "0.14.34", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.34.tgz", - "integrity": "sha512-12seOIk7dv8eAoGQhcWaeKZxNz304IVcDvb9U5Y7JZAEVe21Nm1YMxLjhWah+su5BD4Omx4Zz0z5x3ij9M4GYQ==", + "node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prom-client": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-14.2.0.tgz", + "integrity": "sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA==", + "deprecated": "prom-client has been replaced by @prometheus-io/client", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tdigest": "^0.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prool": { + "version": "0.0.25", + "resolved": "https://registry.npmjs.org/prool/-/prool-0.0.25.tgz", + "integrity": "sha512-RKqgb4iEkKJAQC1U0frPs6DWuC2VRfrn3sRRz09lYVr8GkBjrSH7uQLeA5N0odCRD4x75DfRwOedQTxjMkrYuQ==", + "dev": true, "funding": [ { "type": "github", @@ -1258,111 +5849,96 @@ ], "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.2.3", - "eventemitter3": "5.0.1" + "change-case": "5.4.4", + "eventemitter3": "^5.0.1", + "execa": "^9.1.0", + "get-port": "^7.1.0", + "http-proxy": "^1.18.1", + "tar": "7.2.0" + }, + "engines": { + "node": ">=22" }, "peerDependencies": { - "typescript": ">=5.4.0" + "@pimlico/alto": "*" }, "peerDependenciesMeta": { - "typescript": { + "@pimlico/alto": { "optional": true } } }, - "node_modules/ox/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/prool/node_modules/get-port": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.2.0.tgz", + "integrity": "sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==", + "dev": true, "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=16" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ox/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" + "node_modules/protobufjs": { + "version": "7.6.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz", + "integrity": "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">=12.0.0" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "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": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "node_modules/proxy-addr": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz", + "integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==", "dev": true, "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, "engines": { - "node": ">=12" + "node": ">= 0.10" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/postcss": { - "version": "8.5.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", - "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.17", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, "node_modules/pvtsutils": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.8.1" @@ -1372,26 +5948,176 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.2.0.tgz", "integrity": "sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-native-passkey": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/react-native-passkey/-/react-native-passkey-3.6.1.tgz", + "integrity": "sha512-m3lN9IQvR3rhatmKfviYg7l91Or5QgykIoD5dsDJUvRo4C2Lnm82NbwM9nJ7oXSO3WY1DQig5t/fk9QLx0PYIg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "dev": true, + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ret": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz", + "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=10" } }, - "node_modules/react-native-passkey": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/react-native-passkey/-/react-native-passkey-3.6.1.tgz", - "integrity": "sha512-m3lN9IQvR3rhatmKfviYg7l91Or5QgykIoD5dsDJUvRo4C2Lnm82NbwM9nJ7oXSO3WY1DQig5t/fk9QLx0PYIg==", + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, "license": "MIT", - "peerDependencies": { - "react": "*", - "react-native": "*" + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/reflect-metadata": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", - "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", - "license": "Apache-2.0" + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" }, "node_modules/rolldown": { "version": "1.2.5", @@ -1427,6 +6153,104 @@ "@rolldown/binding-win32-x64-msvc": "1.2.5" } }, + "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==", + "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/safe-regex2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz", + "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==", + "dev": true, + "license": "MIT", + "dependencies": { + "ret": "~0.4.0" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "dev": true, + "license": "MIT" + }, + "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", + "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/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -1434,6 +6258,29 @@ "dev": true, "license": "ISC" }, + "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/sonic-boom": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -1444,6 +6291,16 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -1451,6 +6308,13 @@ "dev": true, "license": "MIT" }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "dev": true, + "license": "MIT" + }, "node_modules/std-env": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", @@ -1458,6 +6322,127 @@ "dev": true, "license": "MIT" }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/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-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "7.5.22", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", + "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tdigest": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.3.tgz", + "integrity": "sha512-zbRt+lT+/H4fRItHshczHErVCQnitJk8MfMT24MqFJf3YL7SJJPqGIGeuOdvxXxM/AHFzKBl7WoyaYwqO9s3Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bintrees": "1.0.2" + } + }, + "node_modules/thread-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz", + "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -1502,16 +6487,28 @@ "node": ">=14.0.0" } }, + "node_modules/toad-cache": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.4.tgz", + "integrity": "sha512-m1TdR/rvT7kgGJZhspNtXdsdYk0fddFpJJFlG5s+UkPFo6lkLoZ3YLOaovPYjq1R75NP5JfeTlSHaOsE09peCg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, "license": "0BSD" }, "node_modules/tsyringe": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "dev": true, "license": "MIT", "dependencies": { "tslib": "^1.9.3" @@ -1524,8 +6521,22 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, "license": "0BSD" }, + "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/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -1547,6 +6558,37 @@ "dev": true, "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/viem": { "version": "2.55.19", "resolved": "https://registry.npmjs.org/viem/-/viem-2.55.19.tgz", @@ -1772,6 +6814,22 @@ } } }, + "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/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -1789,6 +6847,31 @@ "node": ">=8" } }, + "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/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/ws": { "version": "8.21.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", @@ -1809,6 +6892,101 @@ "optional": true } } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yoctocolors": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz", + "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-1.5.0.tgz", + "integrity": "sha512-/7eFkAI4qV0tcxMBB/3+d2c1P6jzzZYdYSlBuAklzMuCrJu5bzJfHS0yVAS87dRHVlhftd6RFJDIvv03JgkSbw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "zod": "^3.18.0" + } } } } diff --git a/package.json b/package.json index 129d544..5361d1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kokio-sdk", - "version": "3.0.2", + "version": "3.1.0", "description": "", "type": "module", "main": "./dist/esm/config.js", @@ -32,10 +32,13 @@ "scripts": { "build": "tsc", "prepack": "npm run build", + "pretest": "npm run build", "test": "vitest run", "test:watch": "vitest", "test:integration": "INTEGRATION=1 vitest run", - "test:integration:fork": "INTEGRATION=1 vitest run tests/integration --no-file-parallelism" + "test:integration:fork": "INTEGRATION=1 vitest run tests/integration --no-file-parallelism", + "test:consumer:fork": "npm run build && INTEGRATION=1 vitest run tests/consumer --no-file-parallelism", + "test:consumer:live": "npm run build && KOKIO_LIVE=1 vitest run tests/consumer --no-file-parallelism" }, "repository": { "type": "git", @@ -48,20 +51,31 @@ }, "homepage": "https://github.com/Blockchain-Powered-eSIM/kokio-sdk#readme", "devDependencies": { + "@pimlico/alto": "0.0.21", + "@pimlico/mock-paymaster": "0.0.8", + "@simplewebauthn/server": "13.3.2", "@types/node": "22.20.1", "dotenv": "17.4.2", + "prool": "0.0.25", + "react-native-passkey": "3.6.1", "typescript": "5.9.3", "vitest": "4.1.11" }, "dependencies": { "@noble/curves": "2.3.0", - "@peculiar/asn1-ecc": "2.9.3", - "@peculiar/asn1-schema": "2.9.3", - "@simplewebauthn/server": "13.3.2", - "react-native-passkey": "3.6.1", + "@scure/base": "1.2.6", "viem": "2.55.19" }, "overrides": { - "ws": "8.21.0" + "ws": "8.21.0", + "tar": "7.5.22" + }, + "peerDependencies": { + "react-native-passkey": "^3.6.1" + }, + "peerDependenciesMeta": { + "react-native-passkey": { + "optional": true + } } } diff --git a/src/admin/PROTOCOL_ADMIN.md b/src/admin/PROTOCOL_ADMIN.md index 23a6d1f..6e01e1e 100644 --- a/src/admin/PROTOCOL_ADMIN.md +++ b/src/admin/PROTOCOL_ADMIN.md @@ -16,7 +16,7 @@ only drive the eSIM wallet admin want [README.md](README.md) instead. | Chain | ProtocolAdmin | Min delay | Floor | |---|---|---|---| -| Base Sepolia (84532) | `0x77A1D6f27462c34BF038832d9Cff6b3E94a9Fe6F` | 2 days | 1 hour | +| Base Sepolia (84532) | `0xdDeCC2C1345BC966337B5f4Fe57EC2D5bfad751A` | 2 days | 1 hour | No other chain is configured. Constructing `KokioAdmin` against one and calling anything throws `UnconfiguredChainError` before a transaction is built. @@ -106,9 +106,7 @@ const call = { }; ``` -`value` is optional and defaults to zero. If you set it, the timelock has to be -holding that ETH when the operation runs, because the call is made from its -address. +`value` is optional and defaults to zero. If you set it, `executor.execute` sends that much ETH from the executing account along with the call, and the timelock passes it on. The timelock does not need to hold it beforehand. ### 2. Schedule diff --git a/src/admin/config-admin.ts b/src/admin/config-admin.ts index fb8f358..67a841b 100644 --- a/src/admin/config-admin.ts +++ b/src/admin/config-admin.ts @@ -21,6 +21,11 @@ export { UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, + BatchSizeOutOfRangeError, + DepositOnResumeError, + ESIMWalletNotLazyDeployedError, + MissingBatchEventError, + StalledBatchError, ContractRevertError, decodeContractRevert, } from "../logic/errors.js"; diff --git a/src/config.ts b/src/config.ts index b4cd2a4..39452e9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -22,6 +22,11 @@ export { UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, + BatchSizeOutOfRangeError, + DepositOnResumeError, + ESIMWalletNotLazyDeployedError, + MissingBatchEventError, + StalledBatchError, ContractRevertError, decodeContractRevert, } from "./logic/errors.js"; diff --git a/src/interface/deviceWalletClass.ts b/src/interface/deviceWalletClass.ts index 7ef1247..f5f3daa 100644 --- a/src/interface/deviceWalletClass.ts +++ b/src/interface/deviceWalletClass.ts @@ -3,6 +3,7 @@ import { _addDeposit, _addESIMWallet, _canPullFunds, + _deployAndBindESIMWallet, _deviceUniqueIdentifier, _entryPoint, _eSIMWalletFactory, @@ -45,6 +46,16 @@ export class DeviceWalletSubPackage { return _addESIMWallet(this.smartAccountClient, this.address, eSIMWalletAddress); } + /** + * Deploy an eSIM wallet and bind it to this device wallet in one user + * operation, optionally granting it access to this wallet's tokens too. + * Resolves once the operation is sent, with its hash and the eSIM wallet's + * address. + */ + deployAndBindESIMWallet (salt: bigint, options: { grantAccessToFunds?: boolean } = {}) { + return _deployAndBindESIMWallet(this.smartAccountClient, this.address, salt, options.grantAccessToFunds ?? false); + } + getVaultAddress () { return _getVaultAddress(this.smartAccountClient, this.address); } diff --git a/src/interface/eSIMWalletClass.ts b/src/interface/eSIMWalletClass.ts index 9193002..3de4b86 100644 --- a/src/interface/eSIMWalletClass.ts +++ b/src/interface/eSIMWalletClass.ts @@ -2,6 +2,7 @@ import { Address, Hex } from "viem"; import { _acceptOwnershipTransfer, _buyDataBundleWithToken, + _buyDataBundleWithTransfer, _priceCapUSDCents, _deviceWallet, _owner, @@ -32,6 +33,15 @@ export class ESIMWalletSubPackage { return _buyDataBundleWithToken(this.client, this.address, dataBundleDetails, asset, maxAmountIn, paymentReference); } + /** + * Same purchase as `buyDataBundleWithToken`, with the device wallet sending + * the tokens it needs in the same user operation. Works without having granted + * this eSIM wallet access to the device wallet's funds. + */ + buyDataBundleWithTransfer (dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex) { + return _buyDataBundleWithTransfer(this.client, this.address, dataBundleDetails, asset, maxAmountIn, paymentReference); + } + priceCapUSDCents () { return _priceCapUSDCents(this.client, this.address); } diff --git a/src/interface/eSIMWalletFactoryClass.ts b/src/interface/eSIMWalletFactoryClass.ts index dcd40d7..9a601e3 100644 --- a/src/interface/eSIMWalletFactoryClass.ts +++ b/src/interface/eSIMWalletFactoryClass.ts @@ -1,7 +1,8 @@ import { Address, WalletClient } from "viem"; import { _deployESIMWalletWithUserOp, - _getCurrentESIMWalletImplementation + _getCurrentESIMWalletImplementation, + _getESIMWalletCounterFactualAddress } from "../logic/eSIMWalletFactory.js" import { KokioSmartAccountClient } from "../types.js"; @@ -15,10 +16,19 @@ export class ESIMWalletFactorySubPackage { this.walletClient = walletClient } + /** + * @deprecated Deploys without binding, so the device wallet does not treat the + * new eSIM wallet as its own. Use `deviceWallet.deployAndBindESIMWallet`. + */ deployESIMWalletWithUserOp (deviceWalletAddress: Address, salt: bigint) { return _deployESIMWalletWithUserOp (this.smartAccountClient, deviceWalletAddress, salt); } + /** Address the eSIM wallet for this device wallet and salt deploys to. */ + getCounterFactualAddress (deviceWalletAddress: Address, salt: bigint) { + return _getESIMWalletCounterFactualAddress(this.smartAccountClient, deviceWalletAddress, salt); + } + getCurrentESIMWalletImplementation () { return _getCurrentESIMWalletImplementation(this.smartAccountClient); } diff --git a/src/interface/registryClass.ts b/src/interface/registryClass.ts index 675d48d..8d2a10e 100644 --- a/src/interface/registryClass.ts +++ b/src/interface/registryClass.ts @@ -27,6 +27,14 @@ export class RegistrySubPackage { this.client = client; } + /** + * Record in the registry that this device wallet holds the eSIM wallet. + * + * Registry side only: the device wallet itself still does not treat the eSIM + * wallet as its own (`isValidESIMWallet` stays false, so it cannot manage it or + * grant it fund access). To take on an eSIM wallet use `deviceWallet.addESIMWallet`, + * which writes both sides. + */ bindESIMWallet (eSIMWalletAddress: Address) { return _bindESIMWallet(this.client, eSIMWalletAddress); } diff --git a/src/interface/smartAccountClass.ts b/src/interface/smartAccountClass.ts index 54674df..cb68b76 100644 --- a/src/interface/smartAccountClass.ts +++ b/src/interface/smartAccountClass.ts @@ -22,7 +22,14 @@ export class SmartAccountSubPackage { return _getSmartWallet(this.client, this.credentialId, this.rpId, deviceUniqueIdentifier, deviceWalletOwnerKey, salt); } - getSmartWalletClient (account: KokioSmartAccount): Promise { - return _getSmartWalletClient(this.client, this.pimlicoAPIKey, this.gasPolicyId, account); + /** + * Client that sends the account's user operations through a bundler, with + * gas sponsored by the paymaster at the same endpoint. + * + * @param options.bundlerUrl Bundler and ERC-7677 paymaster endpoint. Defaults to + * Pimlico for the wallet client's chain, keyed by the API key given to `Kokio`. + */ + getSmartWalletClient (account: KokioSmartAccount, options: { bundlerUrl?: string } = {}): Promise { + return _getSmartWalletClient(this.client, this.pimlicoAPIKey, this.gasPolicyId, account, options.bundlerUrl); } } diff --git a/src/logic/P256Verifier.ts b/src/logic/P256Verifier.ts index 89d7444..3d3396b 100644 --- a/src/logic/P256Verifier.ts +++ b/src/logic/P256Verifier.ts @@ -1,7 +1,7 @@ import { Hex } from "viem"; import { WebAuthnSignature } from "../types.js"; import { KokioSmartAccountClient } from "../types.js"; -import { _getChainSpecificConstants } from "./constants.js"; +import { _chainId, _getChainSpecificConstants } from "./constants.js"; import { P256Verifier } from "../abis/index.js"; // `verifySignature` is a `view` - read it directly instead of spending a userOp @@ -15,7 +15,7 @@ export const _verifySignature = async ( y: bigint ): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/account-kit/createSmartAccount.ts b/src/logic/account-kit/createSmartAccount.ts index 24dffb5..5b18071 100644 --- a/src/logic/account-kit/createSmartAccount.ts +++ b/src/logic/account-kit/createSmartAccount.ts @@ -10,18 +10,22 @@ import { getUserOperationHash, toSmartAccount, type UserOperation } from "viem/account-abstraction"; import { - _getChainSpecificConstants, ZERO, SIGNATURE_VALIDITY_SECONDS, + _chainId, _getChainSpecificConstants, ZERO, SIGNATURE_VALIDITY_SECONDS, STUB_VERIFICATION_GAS_PAD, STUB_PRE_VERIFICATION_GAS_PAD } from "../constants.js"; -import { CounterfactualMismatchError } from "../errors.js"; +import { CounterfactualMismatchError, toContractRevertError } from "../errors.js"; import { _add0x, _concatUint8Arrays, _shouldRemoveLeadingZero } from "../utils.js"; import { P256Key, WebAuthnSignature, KokioSmartAccount, KokioSmartAccountClient } from "../../types.js"; import { DeviceWallet, DeviceWalletFactory } from "../../abis/index.js"; -import { isoBase64URL } from "@simplewebauthn/server/helpers"; +import { base64urlnopad } from "@scure/base"; import { Passkey, PasskeyGetRequest, PasskeyGetResult } from "react-native-passkey"; import { p256 } from "@noble/curves/nist.js"; +// Authenticators differ on padding and alphabet, so accept either form. +const fromBase64URL = (value: string): Uint8Array => + base64urlnopad.decode(value.replace(/=+$/, "").replace(/\+/g, "-").replace(/\//g, "_")); + type BrokenPasskeyGetResult = PasskeyGetResult | string; enum AuthenticatorTransport { @@ -58,10 +62,7 @@ export const BEACON_PROXY_CREATION_CODE: Hex = "0x60a0806040526104e4803803809161 */ export const _stamp = async (credentialId: string, rpId: string, payload: Hex): Promise => { const signingOptions: PasskeyGetRequest = { - // `Uint8Array.from` gives a fresh ArrayBuffer-backed view, matching the - // `Uint8Array` that `fromBuffer` expects (viem's `hexToBytes` - // is typed over the wider `ArrayBufferLike`). - challenge: isoBase64URL.fromBuffer(Uint8Array.from(hexToBytes(payload))), + challenge: base64urlnopad.encode(hexToBytes(payload)), allowCredentials: [{ id: credentialId, type: "public-key", @@ -92,7 +93,7 @@ export const _stamp = async (credentialId: string, rpId: string, payload: Hex): const { clientDataJSON, authenticatorData, signature } = authenticationResult.response; // 1. Decode clientDataJSON - const clientDataJSONBuffer = isoBase64URL.toBuffer(clientDataJSON); + const clientDataJSONBuffer = fromBase64URL(clientDataJSON); const clientDataJSONString = new TextDecoder().decode(clientDataJSONBuffer); // 2. Calculate indices for the contract (byte offsets) @@ -115,18 +116,11 @@ export const _stamp = async (credentialId: string, rpId: string, payload: Hex): } // 3. Decode authenticatorData - const authenticatorDataBytes = isoBase64URL.toBuffer(authenticatorData); + const authenticatorDataBytes = fromBase64URL(authenticatorData); const authenticatorDataHex = bytesToHex(authenticatorDataBytes); // 4. Decode signature (ASN.1 DER encoded) - const signatureBytes = isoBase64URL.toBuffer(signature); - // let parsedSignature = p256.Signature.fromDER(signatureBytes); - let parsedSignature = p256.Signature.fromBytes( - signatureBytes instanceof Uint8Array - ? signatureBytes - : new Uint8Array(signatureBytes), - "der" - ); + let parsedSignature = p256.Signature.fromBytes(fromBase64URL(signature), "der"); // Normalize s const n = p256.Point.CURVE().n; @@ -178,7 +172,7 @@ export const _encodeCalls = async (calls: readonly Call[]): Promise => { export const _getFactoryArgs = async (client: WalletClient, deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key, salt: bigint): Promise<{ factory: Address; factoryData: Hex }> => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -193,7 +187,7 @@ export const _getFactoryArgs = async (client: WalletClient, deviceUniqueIdentifi export const getInitCodeHash = async (client: WalletClient, deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -236,7 +230,7 @@ export const getInitCodeHash = async (client: WalletClient, deviceUniqueIdentifi export const getCounterFactualAddress = async (client: WalletClient, deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key, salt: bigint):Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); const deviceWalletFactoryAddress = values.factoryAddresses.DEVICE_WALLET_FACTORY; @@ -273,26 +267,26 @@ export const _assertCounterfactualMatchesOnChain = async ( deviceWalletOwnerKey: P256Key, salt: bigint, ): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); - const offChain = await getCounterFactualAddress( - client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt, - ); - const deviceWalletFactory = getContract({ abi: DeviceWalletFactory, address: values.factoryAddresses.DEVICE_WALLET_FACTORY, client, }); - // on-chain view arg order is (ownerKey, uid, salt) - differs from createAccount - const onChain = await deviceWalletFactory.read.getCounterFactualAddress([ - deviceWalletOwnerKey, - deviceUniqueIdentifier, - salt, - ]) as Hex; + // Neither side needs the other, so both are asked for at once. + const [offChain, onChain] = await Promise.all([ + getCounterFactualAddress(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt), + // on-chain view arg order is (ownerKey, uid, salt) - differs from createAccount + deviceWalletFactory.read.getCounterFactualAddress([ + deviceWalletOwnerKey, + deviceUniqueIdentifier, + salt, + ]) as Promise, + ]); if (getAddress(offChain) !== getAddress(onChain)) { throw new CounterfactualMismatchError(getAddress(offChain), getAddress(onChain)); @@ -426,12 +420,10 @@ export const _getSmartWallet = async ( salt: bigint ): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); - if (!client.account) throw new Error ('Error: No signer account found with WalletClient') - const accountAddress = _counterfactualVerifiedChains.has(chainID) ? await getCounterFactualAddress(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) : await _assertCounterfactualMatchesOnChain(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt); @@ -548,23 +540,45 @@ const _splitTransport = (pimlicoRpcURL: string, rpcURL: string): Transport => { ); } -export const _getSmartWalletClient = async (client: WalletClient, pimlicoAPIKey: string, gasPolicyId: string, account: KokioSmartAccount): Promise => { +export const _getSmartWalletClient = async ( + client: WalletClient, + pimlicoAPIKey: string, + gasPolicyId: string, + account: KokioSmartAccount, + bundlerUrl?: string +): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL, pimlicoAPIKey); + const bundlerURL = bundlerUrl ?? values.pimlicoRpcURL; - // Pimlico sponsors via ERC-7677, keyed by the gas policy. - const paymaster = createPaymasterClient({ transport: http(values.pimlicoRpcURL) }); + // Pimlico sponsors via ERC-7677 and reads the policy from `sponsorshipPolicyId`. + // A policy is optional there, so an empty id sends no context at all. + const paymaster = createPaymasterClient({ transport: http(bundlerURL) }); - return createBundlerClient({ + const bundlerClient = createBundlerClient({ account, chain: values.chain, client: createPublicClient({ chain: values.chain, transport: http(values.rpcURL) }), - transport: _splitTransport(values.pimlicoRpcURL, values.rpcURL), + transport: _splitTransport(bundlerURL, values.rpcURL), paymaster, - paymasterContext: { policyId: gasPolicyId }, + paymasterContext: gasPolicyId ? { sponsorshipPolicyId: gasPolicyId } : undefined, + }).extend(publicActions); + + // Every user operation the SDK sends goes through here, so a revert is + // decoded once for all of them, the same way admin writes are. + const sendUserOperation = bundlerClient.sendUserOperation; + // extend() keeps the bundler fields at runtime but drops them from the // inferred type, so the result is re-asserted rather than narrowed. - }).extend(publicActions) as unknown as KokioSmartAccountClient; + return bundlerClient.extend(() => ({ + sendUserOperation: (async (args: Parameters[0]) => { + try { + return await sendUserOperation(args); + } catch (err) { + throw toContractRevertError(err) ?? err; + } + }) as typeof sendUserOperation, + })) as unknown as KokioSmartAccountClient; } diff --git a/src/logic/admin/deviceWallet.eoa.ts b/src/logic/admin/deviceWallet.eoa.ts index 57da843..69e1878 100644 --- a/src/logic/admin/deviceWallet.eoa.ts +++ b/src/logic/admin/deviceWallet.eoa.ts @@ -1,5 +1,5 @@ import { Address, WalletClient } from "viem"; -import { _getChainSpecificConstants } from "../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../constants.js"; import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js"; import { DeviceWallet } from "../../abis/index.js"; @@ -22,7 +22,7 @@ export const _deployESIMWallet = async ( salt: bigint ) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -31,7 +31,7 @@ export const _deployESIMWallet = async ( return writeContractOrThrow(client, { address: deviceWalletAddress, chain: values.chain, - account: client.account.address, + account: client.account, abi: DeviceWallet, functionName: 'deployESIMWallet', args: [false, salt] @@ -47,7 +47,7 @@ export const _deployESIMWallet = async ( */ export const _addDeposit = async (client: WalletClient, deviceWalletAddress: Address, amount: bigint) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -56,7 +56,7 @@ export const _addDeposit = async (client: WalletClient, deviceWalletAddress: Add return writeContractOrThrow(client, { address: deviceWalletAddress, chain: values.chain, - account: client.account.address, + account: client.account, abi: DeviceWallet, functionName: 'addDeposit', args: [], diff --git a/src/logic/admin/deviceWalletFactory.eoa.ts b/src/logic/admin/deviceWalletFactory.eoa.ts index 6f70d2c..0dfb01a 100644 --- a/src/logic/admin/deviceWalletFactory.eoa.ts +++ b/src/logic/admin/deviceWalletFactory.eoa.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient } from "viem"; -import { _getChainSpecificConstants } from "../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../constants.js"; import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js"; import { DeviceWalletFactory } from "../../abis/index.js"; import { OwnerCall, P256Key } from "../../types.js"; @@ -31,7 +31,7 @@ export const _deployDeviceWalletForUsers = async ( value: bigint ) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -40,7 +40,7 @@ export const _deployDeviceWalletForUsers = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.DEVICE_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: DeviceWalletFactory, functionName: 'deployDeviceWalletForUsers', args: [deviceUniqueIdentifiers, deviceWalletOwnersKey, salts, depositAmounts], @@ -61,7 +61,7 @@ export const _postCreateAccount = async ( salt: bigint ) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -70,7 +70,7 @@ export const _postCreateAccount = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.DEVICE_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: DeviceWalletFactory, functionName: 'postCreateAccount', args: [deviceWallet, deviceUniqueIdentifier, deviceWalletOwnerKey, salt] @@ -80,7 +80,7 @@ export const _postCreateAccount = async ( /** One-time wiring of the registry into the factory. `onlyAdmin`. */ export const _addRegistryAddress = async (client: WalletClient, registryContractAddress: Address) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -89,7 +89,7 @@ export const _addRegistryAddress = async (client: WalletClient, registryContract return writeContractOrThrow(client, { address: values.factoryAddresses.DEVICE_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: DeviceWalletFactory, functionName: 'addRegistryAddress', args: [registryContractAddress] @@ -99,7 +99,7 @@ export const _addRegistryAddress = async (client: WalletClient, registryContract /** Point the device-wallet beacon at a new implementation. `onlyOwner` (upgradeManager). */ export const _updateDeviceWalletImplementation = async (client: WalletClient, newDeviceImpl: Address) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -108,7 +108,7 @@ export const _updateDeviceWalletImplementation = async (client: WalletClient, ne return writeContractOrThrow(client, { address: values.factoryAddresses.DEVICE_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: DeviceWalletFactory, functionName: 'updateDeviceWalletImplementation', args: [newDeviceImpl] @@ -132,7 +132,7 @@ export const _updateDeviceWalletImplementation = async (client: WalletClient, ne */ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -154,7 +154,7 @@ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Add */ export const _upgradeCall = async (client: WalletClient, newImplementation: Address, data: Hex = '0x'): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -176,7 +176,7 @@ export const _upgradeCall = async (client: WalletClient, newImplementation: Addr */ export const _acceptOwnership = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -185,7 +185,7 @@ export const _acceptOwnership = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.DEVICE_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: DeviceWalletFactory, functionName: 'acceptOwnership', args: [] diff --git a/src/logic/admin/eSIMWallet.eoa.ts b/src/logic/admin/eSIMWallet.eoa.ts index be0fc0f..8a37c90 100644 --- a/src/logic/admin/eSIMWallet.eoa.ts +++ b/src/logic/admin/eSIMWallet.eoa.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient } from "viem"; -import { _getChainSpecificConstants } from "../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../constants.js"; import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js"; import { ESIMWallet } from "../../abis/index.js"; import { DataBundleDetails } from "../../types.js"; @@ -26,7 +26,7 @@ export const _buyDataBundleWithToken = async ( paymentReference: Hex ) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -35,7 +35,7 @@ export const _buyDataBundleWithToken = async ( return writeContractOrThrow(client, { address: eSIMWalletAddress, chain: values.chain, - account: client.account.address, + account: client.account, abi: ESIMWallet, functionName: 'buyDataBundleWithToken', args: [dataBundleDetails, asset, maxAmountIn, paymentReference] diff --git a/src/logic/admin/eSIMWalletFactory.eoa.ts b/src/logic/admin/eSIMWalletFactory.eoa.ts index 1220384..86b0ba2 100644 --- a/src/logic/admin/eSIMWalletFactory.eoa.ts +++ b/src/logic/admin/eSIMWalletFactory.eoa.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient } from "viem"; -import { _getChainSpecificConstants } from "../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../constants.js"; import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js"; import { ESIMWalletFactory } from "../../abis/index.js"; import type { OwnerCall } from "../../types.js"; @@ -19,7 +19,7 @@ import type { OwnerCall } from "../../types.js"; /** One-time wiring of the registry into the eSIM factory. Owner only. */ export const _addRegistryAddress = async (client: WalletClient, registryContractAddress: Address) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -28,7 +28,7 @@ export const _addRegistryAddress = async (client: WalletClient, registryContract return writeContractOrThrow(client, { address: values.factoryAddresses.ESIM_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: ESIMWalletFactory, functionName: 'addRegistryAddress', args: [registryContractAddress] @@ -38,7 +38,7 @@ export const _addRegistryAddress = async (client: WalletClient, registryContract /** Point the eSIM-wallet beacon at a new implementation. `onlyOwner`. */ export const _updateESIMWalletImplementation = async (client: WalletClient, eSIMWalletImpl: Address) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -47,7 +47,7 @@ export const _updateESIMWalletImplementation = async (client: WalletClient, eSIM return writeContractOrThrow(client, { address: values.factoryAddresses.ESIM_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: ESIMWalletFactory, functionName: 'updateESIMWalletImplementation', args: [eSIMWalletImpl] @@ -71,7 +71,7 @@ export const _updateESIMWalletImplementation = async (client: WalletClient, eSIM */ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -92,7 +92,7 @@ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Add */ export const _upgradeCall = async (client: WalletClient, newImplementation: Address, data: Hex = '0x'): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -114,7 +114,7 @@ export const _upgradeCall = async (client: WalletClient, newImplementation: Addr */ export const _acceptOwnership = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -123,7 +123,7 @@ export const _acceptOwnership = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.ESIM_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: ESIMWalletFactory, functionName: 'acceptOwnership', args: [] diff --git a/src/logic/admin/lazyWalletRegistry.eoa.ts b/src/logic/admin/lazyWalletRegistry.eoa.ts index 63f669c..4fb272f 100644 --- a/src/logic/admin/lazyWalletRegistry.eoa.ts +++ b/src/logic/admin/lazyWalletRegistry.eoa.ts @@ -9,7 +9,7 @@ import { parseEventLogs, publicActions, } from "viem"; -import { _getChainSpecificConstants } from "../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../constants.js"; import { BatchSizeOutOfRangeError, DepositOnResumeError, @@ -67,7 +67,7 @@ export const DEFAULT_ESIM_WALLETS_PER_CALL = 10n; export const DEFAULT_HISTORY_ENTRIES_PER_CALL = 25n; const _resolve = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; return _getChainSpecificConstants(chainID, rpcURL); } @@ -91,7 +91,7 @@ export const _batchPopulateHistory = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.LAZY_WALLET_REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: LazyWalletRegistry, functionName: 'batchPopulateHistory', args: [deviceUniqueIdentifiers, eSIMUniqueIdentifiers, dataBundleDetails] @@ -123,7 +123,7 @@ export const _deployLazyWalletAndSetESIMIdentifier = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.LAZY_WALLET_REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: LazyWalletRegistry, functionName: 'deployLazyWalletAndSetESIMIdentifier', args: [deviceOwnerPublicKey, deviceUniqueIdentifier, salt, depositAmount, maxWallets], @@ -153,7 +153,7 @@ export const _deployMoreESIMWalletsForLazyDevice = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.LAZY_WALLET_REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: LazyWalletRegistry, functionName: 'deployMoreESIMWalletsForLazyDevice', args: [deviceUniqueIdentifier, maxWallets] @@ -180,7 +180,7 @@ export const _setHistoryForLazyWallet = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.LAZY_WALLET_REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: LazyWalletRegistry, functionName: 'setHistoryForLazyWallet', args: [eSIMIdentifier, maxEntries] @@ -202,7 +202,7 @@ export const _switchESIMIdentifierToNewDeviceIdentifier = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.LAZY_WALLET_REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: LazyWalletRegistry, functionName: 'switchESIMIdentifierToNewDeviceIdentifier', args: [eSIMIdentifier, oldDeviceIdentifier, newDeviceIdentifier] @@ -347,7 +347,7 @@ export const _deployLazyWalletAllBatches = async ( abi: LazyWalletRegistry, functionName: "deployMoreESIMWalletsForLazyDevice", args: [deviceUniqueIdentifier, maxWallets], - account: client.account.address, + account: client.account, }, "AllESIMWalletsDeployed"); if (finished) { @@ -425,7 +425,7 @@ export const _setHistoryForLazyWalletAllBatches = async ( abi: LazyWalletRegistry, functionName: "setHistoryForLazyWallet", args: [eSIMIdentifier, maxEntries], - account: client.account.address, + account: client.account, }, "HistoryAlreadyCopied"); if (finished) return { eSIMWallet, copied: 0n, batches: [], alreadyComplete: true }; @@ -468,7 +468,7 @@ export const _setHistoryForLazyWalletAllBatches = async ( */ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -491,7 +491,7 @@ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Add */ export const _upgradeCall = async (client: WalletClient, newImplementation: Address, data: Hex = '0x'): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -513,7 +513,7 @@ export const _upgradeCall = async (client: WalletClient, newImplementation: Addr */ export const _acceptOwnership = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -522,7 +522,7 @@ export const _acceptOwnership = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.LAZY_WALLET_REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: LazyWalletRegistry, functionName: 'acceptOwnership', args: [] diff --git a/src/logic/admin/paymentAdapter.eoa.ts b/src/logic/admin/paymentAdapter.eoa.ts index 2374fac..cf2d89f 100644 --- a/src/logic/admin/paymentAdapter.eoa.ts +++ b/src/logic/admin/paymentAdapter.eoa.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient } from "viem"; -import { _getChainSpecificConstants } from "../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../constants.js"; import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js"; import { PaymentAdapter } from "../../abis/index.js"; import type { Asset, OwnerCall } from "../../types.js"; @@ -14,7 +14,7 @@ import type { Asset, OwnerCall } from "../../types.js"; /** Add a currency the adapter has never seen. Reverts if `_symbol` is already registered. Owner only. */ export const _registerAsset = async (client: WalletClient, symbol: Hex, asset: Asset) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -23,7 +23,7 @@ export const _registerAsset = async (client: WalletClient, symbol: Hex, asset: A return writeContractOrThrow(client, { address: values.factoryAddresses.PAYMENT_ADAPTER, chain: values.chain, - account: client.account.address, + account: client.account, abi: PaymentAdapter, functionName: 'registerAsset', args: [symbol, asset] @@ -33,7 +33,7 @@ export const _registerAsset = async (client: WalletClient, symbol: Hex, asset: A /** Change a currency already in the table (its decimals, token, or allowed flag). Owner only. */ export const _updateAsset = async (client: WalletClient, symbol: Hex, asset: Asset) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -42,7 +42,7 @@ export const _updateAsset = async (client: WalletClient, symbol: Hex, asset: Ass return writeContractOrThrow(client, { address: values.factoryAddresses.PAYMENT_ADAPTER, chain: values.chain, - account: client.account.address, + account: client.account, abi: PaymentAdapter, functionName: 'updateAsset', args: [symbol, asset] @@ -60,7 +60,7 @@ export const _updateAsset = async (client: WalletClient, symbol: Hex, asset: Ass /** Add or change a currency, scheduled through the timelock. Pass the result to `schedule`. */ export const _registerAssetCall = async (client: WalletClient, symbol: Hex, asset: Asset): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -75,7 +75,7 @@ export const _registerAssetCall = async (client: WalletClient, symbol: Hex, asse /** Change a currency already in the table, scheduled through the timelock. Pass the result to `schedule`. */ export const _updateAssetCall = async (client: WalletClient, symbol: Hex, asset: Asset): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -95,7 +95,7 @@ export const _updateAssetCall = async (client: WalletClient, symbol: Hex, asset: */ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -110,7 +110,7 @@ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Add /** Point the adapter's proxy at a new implementation. Builds `upgradeToAndCall`. Pass the result to `schedule`. */ export const _upgradeCall = async (client: WalletClient, newImplementation: Address, data: Hex = '0x'): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -132,7 +132,7 @@ export const _upgradeCall = async (client: WalletClient, newImplementation: Addr */ export const _acceptOwnership = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -141,7 +141,7 @@ export const _acceptOwnership = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.PAYMENT_ADAPTER, chain: values.chain, - account: client.account.address, + account: client.account, abi: PaymentAdapter, functionName: 'acceptOwnership', args: [] diff --git a/src/logic/admin/protocolAdmin.eoa.ts b/src/logic/admin/protocolAdmin.eoa.ts index 52bc41d..e42bcc3 100644 --- a/src/logic/admin/protocolAdmin.eoa.ts +++ b/src/logic/admin/protocolAdmin.eoa.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient, encodeFunctionData, publicActions } from "viem"; -import { _getChainSpecificConstants } from "../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../constants.js"; import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js"; import { ProtocolAdmin, Registry } from "../../abis/index.js"; import type { @@ -23,7 +23,7 @@ import type { const ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000" as Hex; const _resolve = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; return _getChainSpecificConstants(chainID, rpcURL); } @@ -168,7 +168,7 @@ export const _schedule = async ( const hash = await writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'schedule', args: [target, value, payload, predecessor, salt, resolvedDelay] @@ -220,7 +220,7 @@ export const _scheduleBatch = async ( const hash = await writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'scheduleBatch', args: [targets, callValues, payloads, predecessor, salt, resolvedDelay] @@ -260,7 +260,7 @@ export const _scheduleRaw = async ( const hash = await writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'schedule', args: [target, value, payload, predecessor, salt, delay] @@ -290,7 +290,7 @@ export const _execute = async (client: WalletClient, operation: ScheduledOperati return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'execute', args: [operation.target, operation.value, operation.payload, operation.predecessor, operation.salt], @@ -308,7 +308,7 @@ export const _executeBatch = async (client: WalletClient, operation: ScheduledBa return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'executeBatch', args: [operation.targets, operation.values, operation.payloads, operation.predecessor, operation.salt], @@ -333,7 +333,7 @@ export const _executeRaw = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'execute', args: [target, value, payload, predecessor, salt], @@ -358,7 +358,7 @@ export const _cancel = async (client: WalletClient, id: Hex) => { return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'cancel', args: [id] @@ -384,7 +384,7 @@ export const _unpauseInstantly = async (client: WalletClient, target: Address) = return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'unpauseInstantly', args: [target] @@ -407,7 +407,7 @@ export const _revokeCancellersInstantly = async (client: WalletClient, accounts: return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'revokeCancellersInstantly', args: [accounts] @@ -433,7 +433,7 @@ export const _disableAdminInstantly = async (client: WalletClient, target?: Addr return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'disableAdminInstantly', args: [target ?? values.factoryAddresses.REGISTRY] @@ -458,7 +458,7 @@ export const _acceptOwnershipBatch = async (client: WalletClient, targets: reado return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'acceptOwnershipBatch', args: [targets] @@ -478,7 +478,7 @@ export const _renounceRole = async (client: WalletClient, role: Hex, account: Ad return writeContractOrThrow(client, { address: values.factoryAddresses.PROTOCOL_ADMIN, chain: values.chain, - account: client.account.address, + account: client.account, abi: ProtocolAdmin, functionName: 'renounceRole', args: [role, account] diff --git a/src/logic/admin/reads/deviceWalletFactory.reads.ts b/src/logic/admin/reads/deviceWalletFactory.reads.ts index 52d561d..4c2efa1 100644 --- a/src/logic/admin/reads/deviceWalletFactory.reads.ts +++ b/src/logic/admin/reads/deviceWalletFactory.reads.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient, publicActions } from "viem"; -import { _getChainSpecificConstants } from "../../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../../constants.js"; import { DeviceWalletFactory } from "../../../abis/index.js"; import { P256Key } from "../../../types.js"; @@ -14,7 +14,7 @@ import { P256Key } from "../../../types.js"; /** The admin EOA (`eSIMWalletAdmin`) currently set on the factory. */ export const _eSIMWalletAdmin = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -29,7 +29,7 @@ export const _eSIMWalletAdmin = async (client: WalletClient): Promise
= /** Whether a device wallet has been registered with the factory. */ export const _deviceWalletInfoAdded = async (client: WalletClient, deviceWallet: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -44,7 +44,7 @@ export const _deviceWalletInfoAdded = async (client: WalletClient, deviceWallet: /** The current device-wallet beacon implementation. */ export const _getCurrentDeviceWalletImplementation = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -74,7 +74,7 @@ export const _preCreateAccountValidation = async ( deviceWalletOwnerKey: P256Key ): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -91,7 +91,7 @@ type AddressGetter = "beacon" | "registry" | "entryPoint" | "verifier" | "owner" const _addressGetter = async (client: WalletClient, functionName: AddressGetter): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -143,7 +143,7 @@ export const _getCounterFactualAddress = async ( salt: bigint ): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -162,7 +162,7 @@ export const _getCounterFactualAddress = async ( */ export const _proxiableUUID = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -177,7 +177,7 @@ export const _proxiableUUID = async (client: WalletClient): Promise => { /** The OpenZeppelin upgrade interface this proxy speaks, currently `"5.0.0"`. */ export const _upgradeInterfaceVersion = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/admin/reads/eSIMWalletFactory.reads.ts b/src/logic/admin/reads/eSIMWalletFactory.reads.ts index ff7e0dc..6cc66b9 100644 --- a/src/logic/admin/reads/eSIMWalletFactory.reads.ts +++ b/src/logic/admin/reads/eSIMWalletFactory.reads.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient, publicActions } from "viem"; -import { _getChainSpecificConstants } from "../../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../../constants.js"; import { ESIMWalletFactory } from "../../../abis/index.js"; // Read-only admin logic for `ESIMWalletFactory` - its public storage getter and @@ -9,7 +9,7 @@ import { ESIMWalletFactory } from "../../../abis/index.js"; /** Whether an eSIM wallet was deployed by this factory. */ export const _isESIMWalletDeployed = async (client: WalletClient, eSIMWallet: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -24,7 +24,7 @@ export const _isESIMWalletDeployed = async (client: WalletClient, eSIMWallet: Ad /** The current eSIM-wallet beacon implementation. */ export const _getCurrentESIMWalletImplementation = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -43,7 +43,7 @@ export const _getCurrentESIMWalletImplementation = async (client: WalletClient): */ export const _proxiableUUID = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -58,7 +58,7 @@ export const _proxiableUUID = async (client: WalletClient): Promise => { /** The OpenZeppelin upgrade interface this proxy speaks, currently `"5.0.0"`. */ export const _upgradeInterfaceVersion = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -77,7 +77,7 @@ export const _upgradeInterfaceVersion = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -96,7 +96,7 @@ export const _owner = async (client: WalletClient): Promise
=> { */ export const _pendingOwner = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/admin/reads/lazyWalletRegistry.reads.ts b/src/logic/admin/reads/lazyWalletRegistry.reads.ts index 01b82f3..1789c04 100644 --- a/src/logic/admin/reads/lazyWalletRegistry.reads.ts +++ b/src/logic/admin/reads/lazyWalletRegistry.reads.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient, publicActions } from "viem"; -import { _getChainSpecificConstants } from "../../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../../constants.js"; import { LazyWalletRegistry } from "../../../abis/index.js"; import { DataBundleDetails } from "../../../types.js"; @@ -15,7 +15,7 @@ import { DataBundleDetails } from "../../../types.js"; /** The upgrade-manager (owner) EOA of the lazy registry. */ export const _upgradeManager = async (client: WalletClient): Promise<`0x${string}`> => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -30,7 +30,7 @@ export const _upgradeManager = async (client: WalletClient): Promise<`0x${string /** The device identifier an eSIM identifier is currently associated with. */ export const _eSIMIdentifierToDeviceIdentifier = async (client: WalletClient, eSIMIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -50,7 +50,7 @@ export const _deviceIdentifierToESIMDetails = async ( index: bigint ): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -67,7 +67,7 @@ export const _deviceIdentifierToESIMDetails = async ( /** Most eSIM wallets one `deployLazyWalletAndSetESIMIdentifier` call will deploy. */ export const _maxESIMWalletsPerCall = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -82,7 +82,7 @@ export const _maxESIMWalletsPerCall = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -101,7 +101,7 @@ export const _maxHistoryEntriesPerCall = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -116,7 +116,7 @@ export const _eSIMWalletsDeployed = async (client: WalletClient, deviceIdentifie /** Salt the device's first deployment batch started from. Every later batch derives from it. */ export const _lazyDeploymentSalt = async (client: WalletClient, deviceIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -134,7 +134,7 @@ export const _lazyDeploymentSalt = async (client: WalletClient, deviceIdentifier */ export const _lazyDeployedESIMWallet = async (client: WalletClient, eSIMIdentifier: string): Promise<`0x${string}`> => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -149,7 +149,7 @@ export const _lazyDeployedESIMWallet = async (client: WalletClient, eSIMIdentifi /** How many of an eSIM's stored purchase entries have already reached its wallet. */ export const _historyEntriesCopied = async (client: WalletClient, eSIMIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -169,7 +169,7 @@ export const _historyEntriesCopied = async (client: WalletClient, eSIMIdentifier */ export const _outstandingHistoryEntries = async (client: WalletClient, eSIMIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -184,7 +184,7 @@ export const _outstandingHistoryEntries = async (client: WalletClient, eSIMIdent /** Whether a device identifier has purchases recorded against it here. */ export const _isDeviceIdentifierReserved = async (client: WalletClient, deviceIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -199,7 +199,7 @@ export const _isDeviceIdentifierReserved = async (client: WalletClient, deviceId /** Whether an eSIM identifier is bound to a device here. */ export const _isESIMIdentifierReserved = async (client: WalletClient, eSIMIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -218,7 +218,7 @@ export const _eSIMIdentifiersAssociatedWithDeviceIdentifier = async ( index: bigint ): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -237,7 +237,7 @@ export const _eSIMIdentifiersAssociatedWithDeviceIdentifier = async ( */ export const _proxiableUUID = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -252,7 +252,7 @@ export const _proxiableUUID = async (client: WalletClient): Promise => { /** The OpenZeppelin upgrade interface this proxy speaks, currently `"5.0.0"`. */ export const _upgradeInterfaceVersion = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -271,7 +271,7 @@ export const _upgradeInterfaceVersion = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -290,7 +290,7 @@ export const _owner = async (client: WalletClient): Promise
=> { */ export const _pendingOwner = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/admin/reads/paymentAdapter.reads.ts b/src/logic/admin/reads/paymentAdapter.reads.ts index 7d51dce..b6e376b 100644 --- a/src/logic/admin/reads/paymentAdapter.reads.ts +++ b/src/logic/admin/reads/paymentAdapter.reads.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient, publicActions } from "viem"; -import { _getChainSpecificConstants } from "../../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../../constants.js"; import { PaymentAdapter } from "../../../abis/index.js"; import { Asset } from "../../../types.js"; @@ -11,7 +11,7 @@ import { Asset } from "../../../types.js"; /** The registry this adapter reads `vault()` and `isESIMWalletValid()` from. */ export const _registry = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -26,7 +26,7 @@ export const _registry = async (client: WalletClient): Promise
=> { /** The ERC-20 registered under the `USDC` symbol at configure time. */ export const _settlementToken = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -45,7 +45,7 @@ export const _settlementToken = async (client: WalletClient): Promise
= */ export const _assets = async (client: WalletClient, symbol: Hex): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -62,7 +62,7 @@ export const _assets = async (client: WalletClient, symbol: Hex): Promise /** A currency's full entry, reverting if the symbol was never registered. */ export const _resolveAsset = async (client: WalletClient, symbol: Hex): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -81,7 +81,7 @@ export const _resolveAsset = async (client: WalletClient, symbol: Hex): Promise< */ export const _quote = async (client: WalletClient, symbol: Hex, priceUSDCents: bigint): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -102,7 +102,7 @@ export const _quote = async (client: WalletClient, symbol: Hex, priceUSDCents: b */ export const _usedReferences = async (client: WalletClient, paymentReference: Hex): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -117,7 +117,7 @@ export const _usedReferences = async (client: WalletClient, paymentReference: He /** The address holding upgrade authority over this adapter (its owner). */ export const _upgradeManager = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/admin/reads/protocolAdmin.reads.ts b/src/logic/admin/reads/protocolAdmin.reads.ts index 0e5aaaf..8457206 100644 --- a/src/logic/admin/reads/protocolAdmin.reads.ts +++ b/src/logic/admin/reads/protocolAdmin.reads.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient, publicActions } from "viem"; -import { _getChainSpecificConstants } from "../../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../../constants.js"; import { ProtocolAdmin } from "../../../abis/index.js"; // Read-only logic for `ProtocolAdmin`, the timelock that owns the four @@ -15,7 +15,7 @@ export enum OperationState { } const _resolve = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; return _getChainSpecificConstants(chainID, rpcURL); } diff --git a/src/logic/admin/reads/registry.reads.ts b/src/logic/admin/reads/registry.reads.ts index 26fdc3d..ddb888b 100644 --- a/src/logic/admin/reads/registry.reads.ts +++ b/src/logic/admin/reads/registry.reads.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient, publicActions } from "viem"; -import { _getChainSpecificConstants } from "../../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../../constants.js"; import { Registry } from "../../../abis/index.js"; // Read-only admin logic for `Registry` (which inherits `RegistryHelper`, so its @@ -14,7 +14,7 @@ import { Registry } from "../../../abis/index.js"; */ export const _eSIMWalletAdmin = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -33,7 +33,7 @@ export const _eSIMWalletAdmin = async (client: WalletClient): Promise
= */ export const _adminOfRecord = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -52,7 +52,7 @@ export const _adminOfRecord = async (client: WalletClient): Promise
=> */ export const _adminDisabled = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -70,7 +70,7 @@ export const _adminDisabled = async (client: WalletClient): Promise => */ export const _paused = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -88,7 +88,7 @@ export const _paused = async (client: WalletClient): Promise => { */ export const _defaultPriceCapUSDCents = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -103,7 +103,7 @@ export const _defaultPriceCapUSDCents = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -118,7 +118,7 @@ export const _vault = async (client: WalletClient): Promise
=> { /** The pending admin nominated via `requestAdminUpdate` (zero address if none). */ export const _newRequestedAdmin = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -137,7 +137,7 @@ export const _newRequestedAdmin = async (client: WalletClient): Promise
*/ export const _owner = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -152,7 +152,7 @@ export const _owner = async (client: WalletClient): Promise
=> { /** The upgrade-manager (owner) EOA recorded in the registry. */ export const _upgradeManager = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -171,7 +171,7 @@ export const _upgradeManager = async (client: WalletClient): Promise
=> */ export const _pendingOwner = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -186,7 +186,7 @@ export const _pendingOwner = async (client: WalletClient): Promise
=> { /** The `DeviceWalletFactory` address wired into the registry. */ export const _deviceWalletFactory = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -201,7 +201,7 @@ export const _deviceWalletFactory = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -216,7 +216,7 @@ export const _eSIMWalletFactory = async (client: WalletClient): Promise
/** The EntryPoint the registry recognises. One per chain. */ export const _entryPoint = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -235,7 +235,7 @@ export const _entryPoint = async (client: WalletClient): Promise
=> { */ export const _requireNotPaused = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -250,7 +250,7 @@ export const _requireNotPaused = async (client: WalletClient): Promise => /** The `LazyWalletRegistry` address wired into the registry. */ export const _lazyWalletRegistry = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -265,7 +265,7 @@ export const _lazyWalletRegistry = async (client: WalletClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -283,7 +283,7 @@ export const _uniqueIdentifierToDeviceWallet = async (client: WalletClient, devi */ export const _deviceWalletToOwner = async (client: WalletClient, deviceWallet: Address, index: bigint): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -298,7 +298,7 @@ export const _deviceWalletToOwner = async (client: WalletClient, deviceWallet: A /** The device wallet registered for a hash of owner P-256 keys (zero if none). */ export const _registeredP256Keys = async (client: WalletClient, hashOfOwnerP256Keys: Hex): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -313,7 +313,7 @@ export const _registeredP256Keys = async (client: WalletClient, hashOfOwnerP256K /** Whether a device wallet is registered/valid. */ export const _isDeviceWalletValid = async (client: WalletClient, deviceWallet: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -336,7 +336,7 @@ export const _isDeviceWalletValid = async (client: WalletClient, deviceWallet: A */ export const _isESIMWalletValid = async (client: WalletClient, eSIMWallet: Address): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -359,7 +359,7 @@ export const _isESIMWalletValid = async (client: WalletClient, eSIMWallet: Addre */ export const _isESIMWalletOnStandby = async (client: WalletClient, eSIMWallet: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -378,7 +378,7 @@ export const _isESIMWalletOnStandby = async (client: WalletClient, eSIMWallet: A */ export const _isDeviceIdentifierAlreadyUsed = async (client: WalletClient, deviceUniqueIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -393,7 +393,7 @@ export const _isDeviceIdentifierAlreadyUsed = async (client: WalletClient, devic /** Whether an eSIM identifier is already held by a wallet. */ export const _isESIMIdentifierClaimed = async (client: WalletClient, eSIMUniqueIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -412,7 +412,7 @@ export const _isESIMIdentifierClaimed = async (client: WalletClient, eSIMUniqueI */ export const _eSIMWalletForIdentifier = async (client: WalletClient, eSIMUniqueIdentifier: string): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -431,7 +431,7 @@ export const _eSIMWalletForIdentifier = async (client: WalletClient, eSIMUniqueI */ export const _claimedESIMIdentifiers = async (client: WalletClient, hashOfESIMIdentifier: Hex): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -454,7 +454,7 @@ export const _claimedESIMIdentifiers = async (client: WalletClient, hashOfESIMId */ export const _requireDeviceIdentifierNotReserved = async (client: WalletClient, deviceUniqueIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -473,7 +473,7 @@ export const _requireDeviceIdentifierNotReserved = async (client: WalletClient, */ export const _proxiableUUID = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -488,7 +488,7 @@ export const _proxiableUUID = async (client: WalletClient): Promise => { /** The OpenZeppelin upgrade interface this proxy speaks, currently `"5.0.0"`. */ export const _upgradeInterfaceVersion = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -503,7 +503,7 @@ export const _upgradeInterfaceVersion = async (client: WalletClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -522,7 +522,7 @@ export const _paymentAdapter = async (client: WalletClient): Promise
=> */ export const _usedPaymentReferences = async (client: WalletClient, scopedReference: Hex): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/admin/registry.eoa.ts b/src/logic/admin/registry.eoa.ts index cb01f40..b5632c7 100644 --- a/src/logic/admin/registry.eoa.ts +++ b/src/logic/admin/registry.eoa.ts @@ -1,5 +1,5 @@ import { Address, Hex, WalletClient } from "viem"; -import { _getChainSpecificConstants } from "../constants.js"; +import { _chainId, _getChainSpecificConstants } from "../constants.js"; import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js"; import { Registry } from "../../abis/index.js"; import type { DataBundleDetails, OwnerCall } from "../../types.js"; @@ -16,7 +16,7 @@ import type { DataBundleDetails, OwnerCall } from "../../types.js"; /** Wire (or rewire) the LazyWalletRegistry into the Registry. `onlyOwner`. */ export const _addOrUpdateLazyWalletRegistryAddress = async (client: WalletClient, lazyWalletRegistry: Address) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -25,7 +25,7 @@ export const _addOrUpdateLazyWalletRegistryAddress = async (client: WalletClient return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'addOrUpdateLazyWalletRegistryAddress', args: [lazyWalletRegistry] @@ -35,7 +35,7 @@ export const _addOrUpdateLazyWalletRegistryAddress = async (client: WalletClient /** Update the vault that receives eSIM payments. `onlyOwner`. */ export const _updateVaultAddress = async (client: WalletClient, newVaultAddress: Address) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -44,7 +44,7 @@ export const _updateVaultAddress = async (client: WalletClient, newVaultAddress: return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'updateVaultAddress', args: [newVaultAddress] @@ -62,7 +62,7 @@ export const _updateVaultAddress = async (client: WalletClient, newVaultAddress: */ export const _requestAdminUpdate = async (client: WalletClient, newAdmin: Address) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -71,7 +71,7 @@ export const _requestAdminUpdate = async (client: WalletClient, newAdmin: Addres return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'requestAdminUpdate', args: [newAdmin] @@ -87,7 +87,7 @@ export const _requestAdminUpdate = async (client: WalletClient, newAdmin: Addres */ export const _disableAdmin = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -96,7 +96,7 @@ export const _disableAdmin = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'disableAdmin', args: [] @@ -112,7 +112,7 @@ export const _disableAdmin = async (client: WalletClient) => { */ export const _enableAdmin = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -121,7 +121,7 @@ export const _enableAdmin = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'enableAdmin', args: [] @@ -139,7 +139,7 @@ export const _enableAdmin = async (client: WalletClient) => { */ export const _pause = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -148,7 +148,7 @@ export const _pause = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'pause', args: [] @@ -164,7 +164,7 @@ export const _pause = async (client: WalletClient) => { */ export const _unpause = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -173,7 +173,7 @@ export const _unpause = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'unpause', args: [] @@ -190,7 +190,7 @@ export const _unpause = async (client: WalletClient) => { */ export const _setDefaultPriceCapUSDCents = async (client: WalletClient, cap: bigint) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -199,7 +199,7 @@ export const _setDefaultPriceCapUSDCents = async (client: WalletClient, cap: big return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'setDefaultPriceCapUSDCents', args: [cap] @@ -218,7 +218,7 @@ export const _assignESIMIdentifier = async ( eSIMUniqueIdentifier: string ) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -227,7 +227,7 @@ export const _assignESIMIdentifier = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'assignESIMIdentifier', args: [eSIMWalletAddress, eSIMUniqueIdentifier] @@ -252,7 +252,7 @@ export const _recordSettledPurchase = async ( paymentReference: Hex ) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -261,7 +261,7 @@ export const _recordSettledPurchase = async ( return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'recordSettledPurchase', args: [eSIMWalletAddress, dataBundleDetail, asset, tokenAmount, paymentReference] @@ -275,7 +275,7 @@ export const _recordSettledPurchase = async ( */ export const _acceptAdminUpdate = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -284,7 +284,7 @@ export const _acceptAdminUpdate = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'acceptAdminUpdate', args: [] @@ -302,7 +302,7 @@ export const _acceptAdminUpdate = async (client: WalletClient) => { */ export const _acceptOwnership = async (client: WalletClient) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -311,7 +311,7 @@ export const _acceptOwnership = async (client: WalletClient) => { return writeContractOrThrow(client, { address: values.factoryAddresses.REGISTRY, chain: values.chain, - account: client.account.address, + account: client.account, abi: Registry, functionName: 'acceptOwnership', args: [] @@ -336,7 +336,7 @@ export const _acceptOwnership = async (client: WalletClient) => { */ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -362,7 +362,7 @@ export const _transferOwnershipCall = async (client: WalletClient, newOwner: Add */ export const _upgradeCall = async (client: WalletClient, newImplementation: Address, data: Hex = '0x'): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/constants.ts b/src/logic/constants.ts index 409ef96..83c4667 100644 --- a/src/logic/constants.ts +++ b/src/logic/constants.ts @@ -83,12 +83,27 @@ export const customErrors: Record = { MISSING_EOA_WALLET: "Error: Client does not have EOA wallet associated" } +// A client's RPC URL is fixed, so its chain id is too. Asking once per client +// saves every later SDK call a round trip to the node. +const chainIds = new WeakMap>(); + +export const _chainId = (client: { getChainId: () => Promise }): Promise => { + let chainId = chainIds.get(client); + if (!chainId) { + chainId = client.getChainId(); + chainIds.set(client, chainId); + // A failed lookup is not remembered, so the next call asks again. + chainId.catch(() => chainIds.delete(client)); + } + return chainId; +} + export const _extractChainID = async (client: WalletClient) => { if (!client) { throw new InvalidClientError(); } - return client.getChainId(); + return _chainId(client); } // Maps each supported chain id to its factory-address book + viem chain. Base diff --git a/src/logic/deviceWallet.ts b/src/logic/deviceWallet.ts index 911260e..d247db3 100644 --- a/src/logic/deviceWallet.ts +++ b/src/logic/deviceWallet.ts @@ -1,8 +1,10 @@ import { Address, encodeFunctionData, getContract, Hex, WalletClient } from "viem"; import { Call, KokioSmartAccountClient } from "../types.js"; -import { DeviceWallet } from "../abis/index.js"; +import { DeviceWallet, ESIMWalletFactory } from "../abis/index.js"; import { MissingSmartWalletError } from "./errors.js"; import { P256Key } from "../types.js"; +import { _chainId, _getChainSpecificConstants } from "./constants.js"; +import { _getESIMWalletCounterFactualAddress } from "./eSIMWalletFactory.js"; // A userOp from a device wallet runs through `execute`, so at the target contract // msg.sender is the device-wallet account itself. That constrains which DeviceWallet @@ -82,6 +84,48 @@ export const _addESIMWallet = async (client: KokioSmartAccountClient, address: A }); } +/** + * Deploy an eSIM wallet for this device wallet and bind it, in one user operation. + * + * Fund access cannot be granted at bind time, so `grantAccessToFunds` adds a + * `toggleAccessToFunds` after the bind in the same operation. The device wallet + * must already be registered (`registry.isDeviceWalletValid`), or the factory + * refuses it. + */ +export const _deployAndBindESIMWallet = async ( + client: KokioSmartAccountClient, + address: Address, + salt: bigint, + grantAccessToFunds: boolean +): Promise<{ userOpHash: Hex; eSIMWalletAddress: Address }> => { + + const chainID = await _chainId(client); + const rpcURL = client.transport.url; + const values = _getChainSpecificConstants(chainID, rpcURL); + + if(!client.account) throw new MissingSmartWalletError(); + + const eSIMWalletAddress = await _getESIMWalletCounterFactualAddress(client, address, salt); + const self = (functionName: "addESIMWallet" | "toggleAccessToFunds", hasAccessToFunds: boolean) => ({ + to: address, + data: encodeFunctionData({ abi: DeviceWallet, functionName, args: [eSIMWalletAddress, hasAccessToFunds] }) + }); + + const userOpHash = await client.sendUserOperation({ + account: client.account, + calls: [ + { + to: values.factoryAddresses.ESIM_WALLET_FACTORY, + data: encodeFunctionData({ abi: ESIMWalletFactory, functionName: "deployESIMWallet", args: [address, salt] }) + }, + self("addESIMWallet", false), + ...(grantAccessToFunds ? [self("toggleAccessToFunds", true)] : []) + ] + }); + + return { userOpHash, eSIMWalletAddress }; +} + /** * Release an eSIM wallet and put it on standby for a transfer. * diff --git a/src/logic/deviceWalletFactory.ts b/src/logic/deviceWalletFactory.ts index 3cad8f7..3d97841 100644 --- a/src/logic/deviceWalletFactory.ts +++ b/src/logic/deviceWalletFactory.ts @@ -1,6 +1,6 @@ import { Address, WalletClient } from "viem"; import { KokioSmartAccountClient } from "../types.js"; -import { _getChainSpecificConstants } from "./constants.js"; +import { _chainId, _getChainSpecificConstants } from "./constants.js"; import { MissingEOAWalletError } from "./errors.js"; import { DeviceWalletFactory } from "../abis/index.js"; import { P256Key } from "../types.js"; @@ -13,7 +13,7 @@ export const _createAccountWithEOA = async ( depositAmount: bigint ) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -24,7 +24,7 @@ export const _createAccountWithEOA = async ( return client.writeContract({ address: values.factoryAddresses.DEVICE_WALLET_FACTORY, chain: values.chain, - account: client.account.address, + account: client.account, abi: DeviceWalletFactory, functionName: 'createAccount', args: [deviceUniqueIdentifier, deviceWalletOwnerKey, salt], @@ -42,7 +42,7 @@ export const _getAddress = async ( salt: bigint, ): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -57,7 +57,7 @@ export const _getAddress = async ( // `getCurrentDeviceWalletImplementation` is a `view` - read it directly instead of a userOp. export const _getCurrentDeviceWalletImplementation = async (client: KokioSmartAccountClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -86,7 +86,7 @@ export const _preCreateAccountValidation = async ( deviceWalletOwnerKey: P256Key ): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -105,7 +105,7 @@ export const _preCreateAccountValidation = async ( */ export const _deviceWalletInfoAdded = async (client: KokioSmartAccountClient, deviceWallet: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -123,7 +123,7 @@ export const _deviceWalletInfoAdded = async (client: KokioSmartAccountClient, de */ export const _beacon = async (client: KokioSmartAccountClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -138,7 +138,7 @@ export const _beacon = async (client: KokioSmartAccountClient): Promise
/** The registry the factory writes new wallets into. */ export const _registry = async (client: KokioSmartAccountClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -153,7 +153,7 @@ export const _registry = async (client: KokioSmartAccountClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -168,7 +168,7 @@ export const _entryPoint = async (client: KokioSmartAccountClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/eSIMWallet.ts b/src/logic/eSIMWallet.ts index 6a5386d..b253997 100644 --- a/src/logic/eSIMWallet.ts +++ b/src/logic/eSIMWallet.ts @@ -1,8 +1,9 @@ -import { Address, Hex, encodeFunctionData, maxUint256 } from "viem" +import { Address, Hex, encodeFunctionData, erc20Abi, maxUint256 } from "viem" import { DataBundleDetails } from "../types.js"; import { KokioSmartAccountClient } from "../types.js"; import { MissingSmartWalletError } from "./errors.js"; -import { ESIMWallet } from "../abis/index.js"; +import { ESIMWallet, PaymentAdapter, Registry } from "../abis/index.js"; +import { _chainId, _getChainSpecificConstants } from "./constants.js"; import { _defaultPriceCapUSDCents } from "./registry.js"; // Not exposed on this surface: @@ -76,6 +77,65 @@ export const _buyDataBundleWithToken = async ( }); } +/** + * Buy a data bundle with tokens the device wallet sends over in the same user + * operation, so the eSIM wallet needs no access to the device wallet's funds. + * + * Only the shortfall is sent: the quote for the bundle minus what this eSIM + * wallet already holds of `asset`. Arguments are as for `buyDataBundleWithToken`. + */ +export const _buyDataBundleWithTransfer = async ( + client: KokioSmartAccountClient, + address: Address, + dataBundleDetails: DataBundleDetails, + asset: Hex, + maxAmountIn: bigint, + paymentReference: Hex +) => { + + const chainID = await _chainId(client); + const rpcURL = client.transport.url; + const values = _getChainSpecificConstants(chainID, rpcURL); + + if(!client.account) throw new MissingSmartWalletError() + + // The eSIM wallet pays through whichever adapter the registry names, so read it there. + const adapter = await client.readContract({ + address: values.factoryAddresses.REGISTRY, abi: Registry, functionName: "paymentAdapter" + }) as Address; + const [{ token }, amountIn] = await Promise.all([ + client.readContract({ + address: adapter, abi: PaymentAdapter, functionName: "resolveAsset", args: [asset] + }) as Promise<{ token: Address }>, + client.readContract({ + address: adapter, abi: PaymentAdapter, functionName: "quote", args: [asset, dataBundleDetails.priceUSDCents] + }) as Promise, + ]); + const held = await client.readContract({ + address: token, abi: erc20Abi, functionName: "balanceOf", args: [address] + }); + + const buy = { + to: address, + data: encodeFunctionData({ + abi: ESIMWallet, + functionName: "buyDataBundleWithToken", + args: [dataBundleDetails, asset, maxAmountIn, paymentReference] + }) + }; + + return client.sendUserOperation({ + account: client.account, + calls: held >= amountIn ? [buy] : [ + { + to: token, + data: encodeFunctionData({ abi: erc20Abi, functionName: "transfer", args: [address, amountIn - held] }) + }, + buy + ] + }); +} + /** * Send an ERC-20 held by this eSIM wallet back to its owning device wallet. * `onlyDeviceWallet`. diff --git a/src/logic/eSIMWalletFactory.ts b/src/logic/eSIMWalletFactory.ts index 5a60fe4..f502b2a 100644 --- a/src/logic/eSIMWalletFactory.ts +++ b/src/logic/eSIMWalletFactory.ts @@ -1,5 +1,5 @@ import { Address, encodeFunctionData } from "viem" -import { _getChainSpecificConstants } from "./constants.js"; +import { _chainId, _getChainSpecificConstants } from "./constants.js"; import { MissingSmartWalletError } from "./errors.js"; import { KokioSmartAccountClient } from "../types.js"; import { ESIMWalletFactory } from "../abis/index.js"; @@ -14,7 +14,7 @@ import { ESIMWalletFactory } from "../abis/index.js"; export const _deployESIMWalletWithUserOp = async (client: KokioSmartAccountClient, deviceWalletAddress: Address, salt: bigint) => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -34,9 +34,24 @@ export const _deployESIMWalletWithUserOp = async (client: KokioSmartAccountClien }); } +/** Address `deployESIMWallet` deploys to for this device wallet and salt. */ +export const _getESIMWalletCounterFactualAddress = async (client: KokioSmartAccountClient, deviceWalletAddress: Address, salt: bigint): Promise
=> { + + const chainID = await _chainId(client); + const rpcURL = client.transport.url; + const values = _getChainSpecificConstants(chainID, rpcURL); + + return client.readContract({ + address: values.factoryAddresses.ESIM_WALLET_FACTORY, + abi: ESIMWalletFactory, + functionName: "getCounterFactualAddress", + args: [deviceWalletAddress, salt] + }) as Promise
; +} + export const _getCurrentESIMWalletImplementation = async (client: KokioSmartAccountClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/errors.ts b/src/logic/errors.ts index 20393db..389807a 100644 --- a/src/logic/errors.ts +++ b/src/logic/errors.ts @@ -22,6 +22,8 @@ import { P256Verifier, Registry, RegistryHelper, + ProtocolAdmin, + PaymentAdapter, } from "../abis/index.js"; /** @@ -212,6 +214,8 @@ const REVERTABLE_ABIS = [ P256Verifier, Registry, RegistryHelper, + ProtocolAdmin, + PaymentAdapter, ] as const; export interface DecodedRevert { @@ -260,22 +264,26 @@ export class ContractRevertError extends KokioError { } /** - * Pulls a ContractRevertError out of an error thrown by viem, or `null` if it - * isn't a revert viem could decode a selector for. + * Pulls a ContractRevertError out of an error thrown by viem, or `null` when + * the error carries no revert data (a network failure, a rejected signature). */ export const toContractRevertError = (err: unknown): ContractRevertError | null => { if (!(err instanceof BaseError)) return null; const revert = err.walk((e) => e instanceof ContractFunctionRevertedError); - if (!(revert instanceof ContractFunctionRevertedError) || !revert.raw) return null; + if (revert instanceof ContractFunctionRevertedError && revert.raw) return new ContractRevertError(revert.raw); - return new ContractRevertError(revert.raw); + // A bundler rejects a reverting user operation while estimating its gas, and + // puts the revert data only in the error message. + const data = err.details?.match(/reverted during simulation with reason: (0x[0-9a-fA-F]+)/)?.[1]; + return data ? new ContractRevertError(data as Hex) : null; }; /** - * `client.writeContract`, but a recognised on-chain revert comes back as a - * ContractRevertError instead of viem's raw error chain. Anything else - - * network failures, an unrecognised revert selector - is rethrown as-is. + * `client.writeContract`, but a revert comes back as a ContractRevertError + * instead of viem's raw error chain. Its `decoded` is null when the selector + * belongs to none of the Kokio contracts. Anything that is not a revert, such + * as a network failure, is rethrown as-is. * * Mirrors `WalletClient["writeContract"]`'s own generics rather than reading * them off `Parameters<...>`, since that would collapse the per-call overload diff --git a/src/logic/paymentAdapter.ts b/src/logic/paymentAdapter.ts index 4445228..a5429ce 100644 --- a/src/logic/paymentAdapter.ts +++ b/src/logic/paymentAdapter.ts @@ -1,5 +1,5 @@ import { Address, Hex } from "viem"; -import { _getChainSpecificConstants } from "./constants.js"; +import { _chainId, _getChainSpecificConstants } from "./constants.js"; import { KokioSmartAccountClient } from "../types.js"; import { Asset } from "../types.js"; import { PaymentAdapter } from "../abis/index.js"; @@ -16,7 +16,7 @@ import { PaymentAdapter } from "../abis/index.js"; */ export const _registry = async (client: KokioSmartAccountClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -31,7 +31,7 @@ export const _registry = async (client: KokioSmartAccountClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -50,7 +50,7 @@ export const _settlementToken = async (client: KokioSmartAccountClient): Promise */ export const _assets = async (client: KokioSmartAccountClient, symbol: Hex): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -72,7 +72,7 @@ export const _assets = async (client: KokioSmartAccountClient, symbol: Hex): Pro */ export const _resolveAsset = async (client: KokioSmartAccountClient, symbol: Hex): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -93,7 +93,7 @@ export const _resolveAsset = async (client: KokioSmartAccountClient, symbol: Hex */ export const _quote = async (client: KokioSmartAccountClient, symbol: Hex, priceUSDCents: bigint): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -114,7 +114,7 @@ export const _quote = async (client: KokioSmartAccountClient, symbol: Hex, price */ export const _usedReferences = async (client: KokioSmartAccountClient, paymentReference: Hex): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -129,7 +129,7 @@ export const _usedReferences = async (client: KokioSmartAccountClient, paymentRe /** The address holding upgrade authority over this adapter (its owner). */ export const _upgradeManager = async (client: KokioSmartAccountClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/registry.ts b/src/logic/registry.ts index af427b7..ad61e85 100644 --- a/src/logic/registry.ts +++ b/src/logic/registry.ts @@ -1,5 +1,5 @@ import { Address, Hex, encodeFunctionData } from "viem"; -import { _getChainSpecificConstants } from "./constants.js"; +import { _chainId, _getChainSpecificConstants } from "./constants.js"; import { KokioSmartAccountClient } from "../types.js"; import { Registry } from "../abis/index.js"; import { MissingSmartWalletError } from "./errors.js"; @@ -31,7 +31,7 @@ export const _bindESIMWallet = async (client: KokioSmartAccountClient, eSIMWalle if(!client.account) throw new MissingSmartWalletError(); - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -64,7 +64,7 @@ export const _toggleESIMWalletStandbyStatus = async ( if(!client.account) throw new MissingSmartWalletError(); - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -89,7 +89,7 @@ export const _toggleESIMWalletStandbyStatus = async ( */ export const _isDeviceIdentifierAlreadyUsed = async (client: KokioSmartAccountClient, deviceUniqueIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -109,7 +109,7 @@ export const _isDeviceIdentifierAlreadyUsed = async (client: KokioSmartAccountCl */ export const _paused = async (client: KokioSmartAccountClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -128,7 +128,7 @@ export const _paused = async (client: KokioSmartAccountClient): Promise */ export const _requireNotPaused = async (client: KokioSmartAccountClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -148,7 +148,7 @@ export const _requireNotPaused = async (client: KokioSmartAccountClient): Promis */ export const _isESIMWalletValid = async (client: KokioSmartAccountClient, eSIMWalletAddress: Address): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -170,7 +170,7 @@ export const _isESIMWalletValid = async (client: KokioSmartAccountClient, eSIMWa */ export const _isESIMWalletOnStandby = async (client: KokioSmartAccountClient, eSIMWalletAddress: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -185,7 +185,7 @@ export const _isESIMWalletOnStandby = async (client: KokioSmartAccountClient, eS /** Whether a device wallet is registered with the protocol. */ export const _isDeviceWalletValid = async (client: KokioSmartAccountClient, deviceWalletAddress: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -200,7 +200,7 @@ export const _isDeviceWalletValid = async (client: KokioSmartAccountClient, devi /** The device wallet registered for a device identifier, zero if none. */ export const _uniqueIdentifierToDeviceWallet = async (client: KokioSmartAccountClient, deviceUniqueIdentifier: string): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -215,7 +215,7 @@ export const _uniqueIdentifierToDeviceWallet = async (client: KokioSmartAccountC /** Whether an eSIM identifier is already held by a wallet. */ export const _isESIMIdentifierClaimed = async (client: KokioSmartAccountClient, eSIMUniqueIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -234,7 +234,7 @@ export const _isESIMIdentifierClaimed = async (client: KokioSmartAccountClient, */ export const _eSIMWalletForIdentifier = async (client: KokioSmartAccountClient, eSIMUniqueIdentifier: string): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -249,7 +249,7 @@ export const _eSIMWalletForIdentifier = async (client: KokioSmartAccountClient, /** The fallback price ceiling in USD cents for a wallet holding no cap of its own. */ export const _defaultPriceCapUSDCents = async (client: KokioSmartAccountClient): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -264,7 +264,7 @@ export const _defaultPriceCapUSDCents = async (client: KokioSmartAccountClient): /** The payment adapter this registry currently points at. */ export const _paymentAdapter = async (client: KokioSmartAccountClient): Promise
=> { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -283,7 +283,7 @@ export const _paymentAdapter = async (client: KokioSmartAccountClient): Promise< */ export const _usedPaymentReferences = async (client: KokioSmartAccountClient, scopedReference: Hex): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -302,7 +302,7 @@ export const _usedPaymentReferences = async (client: KokioSmartAccountClient, sc */ export const _requireLazyHistoryCopied = async (client: KokioSmartAccountClient, eSIMWallet: Address): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); @@ -322,7 +322,7 @@ export const _requireLazyHistoryCopied = async (client: KokioSmartAccountClient, */ export const _requireDeviceIdentifierNotReserved = async (client: KokioSmartAccountClient, deviceUniqueIdentifier: string): Promise => { - const chainID = await client.getChainId(); + const chainID = await _chainId(client); const rpcURL = client.transport.url; const values = _getChainSpecificConstants(chainID, rpcURL); diff --git a/src/logic/utils.ts b/src/logic/utils.ts index 435d3f6..173c795 100644 --- a/src/logic/utils.ts +++ b/src/logic/utils.ts @@ -1,6 +1,4 @@ -import { Hex, isHex, toHex } from "viem"; -import { AsnParser } from "@peculiar/asn1-schema"; -import { ECDSASigValue } from "@peculiar/asn1-ecc"; +import { Hex, isHex } from "viem"; import { NullOrUndefinedValueError } from "./errors.js" export const _add0x = (data: Hex | string): Hex => { @@ -11,14 +9,6 @@ export const _add0x = (data: Hex | string): Hex => { return (data.indexOf('0x') !== -1) ? isHex(data)? data : `0x${data}` : `0x${data}`; } -export const _remove0x = (data: Hex | string): string => { - if(!data) { - throw new NullOrUndefinedValueError(); - } - - return (data.indexOf('0x') !== -1) ? data.slice(2) : data; -} - export function _shouldRemoveLeadingZero(bytes: Uint8Array): boolean { return bytes[0] === 0x0 && (bytes[1] & (1 << 7)) !== 0; } @@ -36,99 +26,3 @@ export function _concatUint8Arrays(arrays: Uint8Array[]): Uint8Array { return toReturn; } - -export function base64UrlToBuffer(base64url: string): Buffer { - const base64 = base64url - .replace(/-/g, "+") - .replace(/_/g, "/") - .padEnd((base64url.length + 3) & ~3, "="); - return Buffer.from(base64, "base64"); -} - -// The WebAuthn CollectedClientData object (WebAuthn Level 2, §5.8.1). Optional -// fields appear only in some authenticator/browser combinations. -export interface ClientDataJSON { - type: string; - challenge: string; - origin: string; - crossOrigin?: boolean; - [key: string]: unknown; -} - -export function decodeClientDataJSON(base64url: string): ClientDataJSON { - const base64 = base64url - .replace(/-/g, "+") - .replace(/_/g, "/") - .padEnd((base64url.length + 3) & ~3, "="); - const jsonString = Buffer.from(base64, "base64").toString("utf-8"); - return JSON.parse(jsonString) as ClientDataJSON; -} - -export function hexToArrayBuffer(hexString: string): ArrayBuffer { - const cleanHex = hexString.startsWith("0x") ? hexString.slice(2) : hexString; - const bytes = new Uint8Array(cleanHex.length / 2); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = parseInt(cleanHex.substr(i * 2, 2), 16); - } - return bytes.buffer; -} - -export function parseDEREncodedSignature(signature: Uint8Array): { - r: string; - s: string; - } { - let offset = 0; - if (signature[offset++] !== 0x30) throw new Error("Invalid DER sequence"); - - // Sequence length byte. Skipped, because r and s each carry their own length. - offset++; - if (signature[offset++] !== 0x02) throw new Error("Expected integer for r"); - - const rLen = signature[offset++]; - const r = signature.slice(offset, offset + rLen); - offset += rLen; - - if (signature[offset++] !== 0x02) throw new Error("Expected integer for s"); - const sLen = signature[offset++]; - const s = signature.slice(offset, offset + sLen); - - return { - r: Buffer.from(r).toString("hex"), - s: Buffer.from(s).toString("hex"), - }; -} - -export function shouldRemoveLeadingZero(bytes: Uint8Array): boolean { - return bytes[0] === 0x0 && (bytes[1] & (1 << 7)) !== 0; -} - -export function concatUint8Arrays(arrays: Uint8Array[]): Uint8Array { - let pointer = 0; - const totalLength = arrays.reduce((prev, curr) => prev + curr.length, 0); - - const toReturn = new Uint8Array(totalLength); - - arrays.forEach((arr) => { - toReturn.set(arr, pointer); - pointer += arr.length; - }); - - return toReturn; -} - -export function parseSignature(signature: Uint8Array) { - const parsedSignature = AsnParser.parse(signature, ECDSASigValue); - let rBytes = new Uint8Array(parsedSignature.r); - let sBytes = new Uint8Array(parsedSignature.s); - if (shouldRemoveLeadingZero(rBytes)) { - rBytes = rBytes.slice(1); - } - if (shouldRemoveLeadingZero(sBytes)) { - sBytes = sBytes.slice(1); - } - const finalSignature = concatUint8Arrays([rBytes, sBytes]); - return { - r: toHex(finalSignature.slice(0, 32)), - s: toHex(finalSignature.slice(32)), - }; -} diff --git a/src/types.ts b/src/types.ts index cbd127c..2983fa7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -23,7 +23,7 @@ export type OwnerCall = { abi: Abi; functionName: string; args?: readonly unknown[]; - /** ETH sent with the call. The timelock has to be holding it. */ + /** ETH sent with the call. `executor.execute` attaches it from the executing account. */ value?: bigint; } diff --git a/tests/README.md b/tests/README.md index 00e7f25..1fcad5d 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,6 +1,6 @@ # tests -Three tiers, only the first of which runs by default. +Four tiers, only the first of which runs by default. ## Unit tests (default) @@ -19,11 +19,24 @@ The [integration/](integration/) folder holds two opt-in tiers that are skipped unless explicitly enabled, so `npm test` stays offline and green: - a read-only parity check that reads a live Base Sepolia deployment, and -- a local `anvil` fork that exercises real admin writes and a software-P-256 user - operation with no private keys and no bundler. +- a local `anvil` fork that exercises real admin writes, ERC-1271 signatures and lazy deployment, with no private keys and no bundler. Prerequisites, environment variables, and the exact commands are documented in [integration/README.md](integration/README.md). +## Consumer tests (opt-in) + +The [consumer/](consumer/) folder uses the SDK the way an app or backend would: it imports `kokio-sdk` by package name from the built `dist/`, never from `src/`. Only the passkey prompt is replaced, by a software signer. + +- `*.fork.test.ts` runs the whole user journey on an anvil fork of Base Sepolia, through a local Alto bundler and mock paymaster: deploy a device wallet, register it, deploy and bind an eSIM wallet, grant and revoke access, buy with `USDC` and `USDCt`, and the refusals. Every user operation must be sponsored. Needs Foundry's `anvil`. +- `*.live.test.ts` runs the same journey on Base Sepolia with Pimlico. It sends real testnet transactions and reads `BASE_SEPOLIA_RPC_URL`, `PIMLICO_API_SECRET` and `ESIM_WALLET_ADMIN_PK` (the registry's eSIM wallet admin) from `.env`. `PIMLICO_POLICY_ID` is optional. The admin account needs a little ETH and at least 1 USDCt. + +```sh +npm run test:consumer:fork +npm run test:consumer:live +``` + +Test data carries the `kokio-sdk-test` tag, so it is easy to tell apart from other activity on Base Sepolia. + Shared test helpers live in [utils/](utils/): the mock client, a live client factory, the fork lifecycle, and the test-only software P-256 signer. diff --git a/tests/consumer/adminJourney.fork.test.ts b/tests/consumer/adminJourney.fork.test.ts new file mode 100644 index 0000000..af27048 --- /dev/null +++ b/tests/consumer/adminJourney.fork.test.ts @@ -0,0 +1,66 @@ +import { afterAll, beforeAll, describe, expect, it } from "vitest"; +import { createWalletClient, http, parseEther, type Address, type WalletClient } from "viem"; +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; +import { baseSepolia } from "viem/chains"; + +import { KokioAdmin } from "kokio-sdk/admin"; +import { DeviceWalletFactory } from "kokio-sdk/abis"; + +import { impersonateRegistryOwner, startFork, type Fork } from "../utils/forkChain.js"; +import { createSoftSigner } from "../utils/softP256Signer.js"; +import { testDeviceId } from "./fixtures/testLabels.js"; + +const DEVICE_WALLET_FACTORY: Address = "0x0BB3BA8D9233514a4aA6D72c243a2473f9cFf0bb"; + +// A backend holds its admin key locally and talks to a hosted RPC that has no +// accounts of its own, so every admin write has to be signed in process. The +// key here is fresh, so anvil cannot sign for it either, which is what makes a +// write sent as a bare address fail the way it would against a hosted RPC. +describe("backend admin with a local private key on a Base Sepolia fork", () => { + let fork: Fork; + let backend: WalletClient; + let admin: KokioAdmin; + + beforeAll(async () => { + fork = await startFork(); + + const account = privateKeyToAccount(generatePrivateKey()); + await fork.testClient.setBalance({ address: account.address, value: parseEther("1") }); + backend = createWalletClient({ account, chain: baseSepolia, transport: http(fork.rpcUrl) }); + admin = new KokioAdmin(backend); + + // The registry's owner (the timelock on the live deployment) nominates the backend. + const { client: owner } = await impersonateRegistryOwner(fork); + const hash = await new KokioAdmin(owner).registry.requestAdminUpdate(account.address); + await fork.publicClient.waitForTransactionReceipt({ hash }); + }, 120_000); + + afterAll(async () => { + await fork?.stop(); + }); + + it("accepts the admin role", async () => { + const hash = await admin.registry.acceptAdminUpdate(); + await fork.publicClient.waitForTransactionReceipt({ hash }); + + expect(await admin.registry.eSIMWalletAdmin()).toBe(backend.account!.address); + }, 60_000); + + it("registers a device wallet deployed through the permissionless route", async () => { + const uid = testDeviceId(); + const { ownerKey } = createSoftSigner(); + const salt = 7n; + + const deploy = await fork.funded.writeContract({ + address: DEVICE_WALLET_FACTORY, abi: DeviceWalletFactory, functionName: "createAccount", + args: [uid, ownerKey, salt], chain: baseSepolia, account: fork.funded.account!, + }); + await fork.publicClient.waitForTransactionReceipt({ hash: deploy }); + const deviceWallet = await admin.deviceWalletFactory.getCounterFactualAddress(ownerKey, uid, salt); + + const hash = await admin.deviceWalletFactory.postCreateAccount(deviceWallet, uid, ownerKey, salt); + await fork.publicClient.waitForTransactionReceipt({ hash }); + + expect(await admin.registry.isDeviceWalletValid(deviceWallet)).toBe(true); + }, 60_000); +}); diff --git a/tests/consumer/fixtures/forkStack.ts b/tests/consumer/fixtures/forkStack.ts new file mode 100644 index 0000000..28e8cc9 --- /dev/null +++ b/tests/consumer/fixtures/forkStack.ts @@ -0,0 +1,107 @@ +import { spawn, type ChildProcess } from "node:child_process"; +import { mkdtempSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { paymaster } from "@pimlico/mock-paymaster"; + +import { freePort, startFork, type Fork } from "../../utils/forkChain.js"; + +// A local stand-in for Pimlico: an anvil fork of Base Sepolia, an Alto bundler on +// it, and the mock paymaster in front of Alto. The mock paymaster answers the +// ERC-7677 methods and forwards every bundler method to Alto, so one URL serves +// both roles, as api.pimlico.io does. + +const ENTRY_POINT_08 = "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"; + +// anvil dev accounts 1 and 2, funded on every fork. Account 0 is the fork's own +// `funded` client, so the bundler never races the test for a nonce. +const EXECUTOR_PK = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"; +const UTILITY_PK = "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"; + +const ALTO_CLI = fileURLToPath(new URL("../../../node_modules/@pimlico/alto/esm/cli/alto.js", import.meta.url)); + +export interface ForkStack { + fork: Fork; + /** Bundler and paymaster endpoint, passed to `getSmartWalletClient`. */ + bundlerUrl: string; + stop: () => Promise; +} + +const answersRpc = async (url: string): Promise => { + try { + const res = await fetch(url, { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_supportedEntryPoints", params: [] }), + }); + return res.ok; + } catch { + return false; + } +}; + +const startAlto = async (rpcUrl: string, port: number): Promise => { + // Alto loads a .env from its working directory on start. Run it from an empty + // temp directory with dotenv pointed at nothing, so it only sees these flags. + const proc = spawn( + process.execPath, + [ + ALTO_CLI, + "--entrypoints", ENTRY_POINT_08, + "--rpc-url", rpcUrl, + "--executor-private-keys", EXECUTOR_PK, + "--utility-private-key", UTILITY_PK, + "--port", String(port), + // Safe mode needs a tracer anvil does not provide. + "--safe-mode", "false", + "--log-level", "warn", + ], + { + cwd: mkdtempSync(join(tmpdir(), "kokio-alto-")), + env: { ...process.env, DOTENV_CONFIG_PATH: "/dev/null" }, + stdio: ["ignore", "ignore", "pipe"], + }, + ); + + let stderr = ""; + proc.stderr?.on("data", (chunk) => { stderr += chunk; }); + + const url = `http://127.0.0.1:${port}`; + const deadline = Date.now() + 60_000; + while (!(await answersRpc(url))) { + if (proc.exitCode !== null || Date.now() > deadline) { + proc.kill("SIGKILL"); + throw new Error(`Alto did not start on ${url}:\n${stderr}`); + } + await new Promise((r) => setTimeout(r, 250)); + } + + return proc; +}; + +/** Start the fork, bundler and paymaster. Throws if any of them cannot start. */ +export const startForkStack = async (): Promise => { + const [anvilPort, altoPort, paymasterPort] = await Promise.all([freePort(), freePort(), freePort()]); + + const fork = await startFork(anvilPort); + const alto = await startAlto(fork.rpcUrl, altoPort); + + const pm = paymaster({ + anvilRpc: fork.rpcUrl, + altoRpc: `http://127.0.0.1:${altoPort}`, + port: paymasterPort, + host: "127.0.0.1", + }); + await pm.start(); + + return { + fork, + bundlerUrl: `http://127.0.0.1:${paymasterPort}`, + stop: async () => { + await pm.stop(); + alto.kill("SIGTERM"); + await fork.stop(); + }, + }; +}; diff --git a/tests/consumer/fixtures/liveStack.ts b/tests/consumer/fixtures/liveStack.ts new file mode 100644 index 0000000..e4aca78 --- /dev/null +++ b/tests/consumer/fixtures/liveStack.ts @@ -0,0 +1,78 @@ +// The live tier reads its keys from the environment, loaded here from .env the +// same way the fork harness does. +import "dotenv/config"; +import { createPublicClient, createWalletClient, erc20Abi, http, type Address, type Hex, type PublicClient, type WalletClient } from "viem"; +import { nonceManager, privateKeyToAccount } from "viem/accounts"; +import { baseSepolia } from "viem/chains"; +import { KokioAdmin } from "kokio-sdk/admin"; + +import type { UserTarget } from "./user.js"; + +export interface LiveStack { + target: UserTarget; + publicClient: PublicClient; + /** The backend: the registry's eSIM wallet admin, signing with its own key. */ + admin: KokioAdmin; + adminClient: WalletClient; +} + +const required = (name: string): string => { + const value = process.env[name]; + if (!value) throw new Error(`${name} is not set. The live tier needs it; see TEST_PLAN.md.`); + return value; +}; + +/** Build the live clients, and check the admin key is the one the registry trusts. */ +export const startLiveStack = async (): Promise => { + const rpcUrl = required("BASE_SEPOLIA_RPC_URL"); + const target: UserTarget = { + rpcUrl, + pimlicoAPIKey: required("PIMLICO_API_SECRET"), + // Optional: Pimlico sponsors without a policy. + policyId: process.env.PIMLICO_POLICY_ID ?? "", + }; + + // Cast because viem types an OP Stack client's blocks more narrowly than the generic one. + const publicClient = createPublicClient({ chain: baseSepolia, transport: http(rpcUrl) }) as PublicClient; + const adminClient = createWalletClient({ + // Hosted RPCs balance reads across nodes, and a node that is a block behind + // hands out a nonce already used. Counting locally avoids that. + account: privateKeyToAccount(required("ESIM_WALLET_ADMIN_PK") as Hex, { nonceManager }), + chain: baseSepolia, + transport: http(rpcUrl), + }); + const admin = new KokioAdmin(adminClient); + + const onRecord = await admin.registry.eSIMWalletAdmin(); + if (onRecord !== adminClient.account!.address) { + throw new Error(`ESIM_WALLET_ADMIN_PK is ${adminClient.account!.address}, but the registry's admin is ${onRecord}.`); + } + + return { target, publicClient, admin, adminClient }; +}; + +/** Send `amount` of `token` from the admin to `to`, after checking the admin holds it. */ +export const fundFromAdmin = async (live: LiveStack, token: Address, to: Address, amount: bigint) => { + const from = live.adminClient.account!.address; + const held = await live.publicClient.readContract({ address: token, abi: erc20Abi, functionName: "balanceOf", args: [from] }); + if (held < amount) { + // The token is whatever the adapter resolves the asset to, so name it rather than guess a faucet. + throw new Error(`The admin ${from} holds ${held} of ${token} and the purchase needs ${amount}. Send it some of that token.`); + } + + const hash = await live.adminClient.writeContract({ + address: token, abi: erc20Abi, functionName: "transfer", args: [to, amount], + account: live.adminClient.account!, chain: baseSepolia, + }); + await confirmed(live, hash); +}; + +/** + * Wait until a transaction is a few blocks deep and check it succeeded. A single + * confirmation is not enough: the next read, or Pimlico's simulation, can land on + * a node that has not seen the block yet. + */ +export const confirmed = async (live: LiveStack, hash: Hex) => { + const receipt = await live.publicClient.waitForTransactionReceipt({ hash, confirmations: 3 }); + if (receipt.status !== "success") throw new Error(`Transaction ${hash} reverted.`); +}; diff --git a/tests/consumer/fixtures/passkeyAuthenticator.ts b/tests/consumer/fixtures/passkeyAuthenticator.ts new file mode 100644 index 0000000..f12baf4 --- /dev/null +++ b/tests/consumer/fixtures/passkeyAuthenticator.ts @@ -0,0 +1,23 @@ +import { hexToBytes, toHex } from "viem"; +import { p256 } from "@noble/curves/nist.js"; +import { isoBase64URL } from "@simplewebauthn/server/helpers"; + +import type { SoftSigner } from "../../utils/softP256Signer.js"; + +const N = p256.Point.CURVE().n; + +// What `Passkey.get` from react-native-passkey returns, produced by a software +// key. The SDK decodes it exactly as it decodes a real device's assertion. +// Real authenticators return a high s about half the time, which `highS` forces. +export const asPasskey = (signer: SoftSigner, { highS = false } = {}) => async (options: { challenge: string }) => { + const assertion = signer.stamp(toHex(isoBase64URL.toBuffer(options.challenge))); + const s = highS ? N - assertion.s : assertion.s; + + return { + response: { + clientDataJSON: isoBase64URL.fromBuffer(new TextEncoder().encode(assertion.clientDataJSON)), + authenticatorData: isoBase64URL.fromBuffer(Uint8Array.from(hexToBytes(assertion.authenticatorData))), + signature: isoBase64URL.fromBuffer(new p256.Signature(assertion.r, s).toBytes("der")), + }, + }; +}; diff --git a/tests/consumer/fixtures/sponsorship.ts b/tests/consumer/fixtures/sponsorship.ts new file mode 100644 index 0000000..1f7c547 --- /dev/null +++ b/tests/consumer/fixtures/sponsorship.ts @@ -0,0 +1,45 @@ +import { expect } from "vitest"; +import { zeroAddress, type Address, type Hex, type PublicClient } from "viem"; +import type { KokioSmartAccountClient } from "kokio-sdk/types"; + +const ENTRY_POINT_08 = "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"; +const balanceOfAbi = [{ + type: "function", name: "balanceOf", stateMutability: "view", + inputs: [{ name: "account", type: "address" }], outputs: [{ type: "uint256" }], +}] as const; + +const spendable = async (reader: PublicClient, sender: Address) => ({ + eth: await reader.getBalance({ address: sender }), + deposit: await reader.readContract({ address: ENTRY_POINT_08, abi: balanceOfAbi, functionName: "balanceOf", args: [sender] }), +}); + +/** + * Run `send`, wait for its user operation, and check it succeeded with a paymaster + * covering gas: the sender's ETH and EntryPoint deposit are both unchanged, which + * an operation it paid for itself cannot manage. + * + * On a hosted RPC pass a few `confirmations`, so reads after this do not land on + * a node that has not seen the block yet. + */ +export const expectSponsored = async ( + client: KokioSmartAccountClient, + reader: PublicClient, + send: () => Promise, + { confirmations = 1 } = {}, +) => { + const sender = client.account!.address; + const before = await spendable(reader, sender); + + const hash = await send(); + const receipt = await client.waitForUserOperationReceipt({ hash, timeout: 120_000 }); + if (confirmations > 1) { + await reader.waitForTransactionReceipt({ hash: receipt.receipt.transactionHash, confirmations }); + } + + expect(receipt.success, `user operation ${hash} reverted`).toBe(true); + expect(receipt.paymaster).not.toBe(zeroAddress); + expect(await reader.getCode({ address: receipt.paymaster! })).toMatch(/^0x[0-9a-f]+$/i); + expect(await spendable(reader, sender)).toEqual(before); + + return receipt; +}; diff --git a/tests/consumer/fixtures/testLabels.ts b/tests/consumer/fixtures/testLabels.ts new file mode 100644 index 0000000..c67a15d --- /dev/null +++ b/tests/consumer/fixtures/testLabels.ts @@ -0,0 +1,16 @@ +import { stringToHex, type Hex } from "viem"; + +// Everything these suites put onchain carries this tag, so their wallets and +// purchases on Base Sepolia are easy to tell apart from people testing the app. +export const TEST_TAG = "kokio-sdk-test"; + +export const RP_ID = `${TEST_TAG}.local`; +export const CREDENTIAL_ID = `${TEST_TAG}-credential`; +/** Stand-in policy id for the fork, where the mock paymaster sponsors everything. */ +export const FORK_POLICY_ID = `sp_${TEST_TAG}`; + +/** Device identifier, unique per run. Emitted as-is in `DeviceWalletInfoUpdated`. */ +export const testDeviceId = () => `${TEST_TAG}-device-${Date.now()}`; + +/** A bytes32 that reads as `kokio-sdk-test:` on a block explorer. */ +export const testBytes32 = (name: string): Hex => stringToHex(`${TEST_TAG}:${name}`, { size: 32 }); diff --git a/tests/consumer/fixtures/tokens.ts b/tests/consumer/fixtures/tokens.ts new file mode 100644 index 0000000..fab6310 --- /dev/null +++ b/tests/consumer/fixtures/tokens.ts @@ -0,0 +1,24 @@ +import { encodeAbiParameters, erc20Abi, keccak256, toHex, type Address } from "viem"; + +import type { Fork } from "../../utils/forkChain.js"; + +// Give `holder` exactly `amount` of `token` on the fork by writing its balance +// slot. The slot index of the balances mapping differs per token, so this tries +// the usual ones and keeps the first that `balanceOf` reports back. +export const setTokenBalance = async (fork: Fork, token: Address, holder: Address, amount: bigint) => { + const readBalance = () => fork.publicClient.readContract({ + address: token, abi: erc20Abi, functionName: "balanceOf", args: [holder], + }); + + for (let index = 0n; index < 20n; index++) { + const slot = keccak256(encodeAbiParameters([{ type: "address" }, { type: "uint256" }], [holder, index])); + const previous = await fork.publicClient.getStorageAt({ address: token, slot }); + + await fork.testClient.setStorageAt({ address: token, index: slot, value: toHex(amount, { size: 32 }) }); + if ((await readBalance()) === amount) return; + + await fork.testClient.setStorageAt({ address: token, index: slot, value: previous ?? toHex(0n, { size: 32 }) }); + } + + throw new Error(`no balance slot found for ${token}`); +}; diff --git a/tests/consumer/fixtures/user.ts b/tests/consumer/fixtures/user.ts new file mode 100644 index 0000000..b5cb697 --- /dev/null +++ b/tests/consumer/fixtures/user.ts @@ -0,0 +1,57 @@ +import type { Mock } from "vitest"; +import { createWalletClient, http, type Address } from "viem"; +import { baseSepolia } from "viem/chains"; +import { Kokio } from "kokio-sdk"; +import type { KokioSmartAccount, KokioSmartAccountClient } from "kokio-sdk/types"; + +import { createSoftSigner, type SoftSigner } from "../../utils/softP256Signer.js"; +import { asPasskey } from "./passkeyAuthenticator.js"; +import type { ForkStack } from "./forkStack.js"; +import { CREDENTIAL_ID, FORK_POLICY_ID, RP_ID, testDeviceId } from "./testLabels.js"; + +export interface TestUser { + uid: string; + salt: bigint; + signer: SoftSigner; + account: KokioSmartAccount; + client: KokioSmartAccountClient; + /** Built with the smart account client and the device wallet, as an app does after setup. */ + kokio: Kokio; + deviceWallet: Address; +} + +/** Where a test user's wallet lives: a fork with local stand-ins, or Base Sepolia with Pimlico. */ +export interface UserTarget { + rpcUrl: string; + /** Left out to use Pimlico, as an app does. */ + bundlerUrl?: string; + pimlicoAPIKey: string; + policyId: string; +} + +export const forkTarget = (stack: ForkStack): UserTarget => ({ + rpcUrl: stack.fork.rpcUrl, + bundlerUrl: stack.bundlerUrl, + pimlicoAPIKey: "unused-on-fork", + policyId: FORK_POLICY_ID, +}); + +// What an app does when a user first opens it: a passkey, a wallet client with +// no account, the counterfactual smart account and its bundler client. Nothing is +// deployed yet. `passkeyGet` is the suite's mocked `Passkey.get`, pointed at this +// user's key. +export const createTestUser = async (target: UserTarget, passkeyGet: Mock): Promise => { + const uid = testDeviceId(); + const salt = BigInt(Date.now()); + const signer = createSoftSigner(RP_ID); + passkeyGet.mockImplementation(asPasskey(signer)); + + const walletClient = createWalletClient({ chain: baseSepolia, transport: http(target.rpcUrl) }); + + const setup = new Kokio(walletClient, CREDENTIAL_ID, RP_ID, target.pimlicoAPIKey, target.policyId); + const account = await setup.smartAccount.getSmartWallet(uid, signer.ownerKey, salt); + const client = await setup.smartAccount.getSmartWalletClient(account, { bundlerUrl: target.bundlerUrl }); + const kokio = new Kokio(walletClient, CREDENTIAL_ID, RP_ID, target.pimlicoAPIKey, target.policyId, client, account.address); + + return { uid, salt, signer, account, client, kokio, deviceWallet: account.address }; +}; diff --git a/tests/consumer/packageExports.test.ts b/tests/consumer/packageExports.test.ts new file mode 100644 index 0000000..f3de09a --- /dev/null +++ b/tests/consumer/packageExports.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, it, vi } from "vitest"; + +// Node cannot load the native passkey module, so an app's test setup has to stub +// it the same way. Nothing here signs, so an empty stub is enough. +vi.mock("react-native-passkey", () => ({ Passkey: {} })); + +import * as root from "kokio-sdk"; +import * as admin from "kokio-sdk/admin"; +import * as types from "kokio-sdk/types"; +import * as abis from "kokio-sdk/abis"; + +// Imports go through the package name, so they resolve through package.json +// `exports` to the built dist/ exactly as they do for an installed copy. + +const ERROR_CLASSES = [ + "KokioError", + "NullOrUndefinedValueError", + "MissingSmartWalletError", + "MissingEOAWalletError", + "InvalidClientError", + "UnsupportedChainError", + "UnconfiguredChainError", + "CounterfactualMismatchError", + "ContractRevertError", + "BatchSizeOutOfRangeError", + "DepositOnResumeError", + "ESIMWalletNotLazyDeployedError", + "MissingBatchEventError", + "StalledBatchError", +] as const; + +describe("package entry points", () => { + it("kokio-sdk exports Kokio, the error classes and the revert decoder", () => { + expect(typeof root.Kokio).toBe("function"); + expect(typeof root.decodeContractRevert).toBe("function"); + for (const name of ERROR_CLASSES) { + expect(root, name).toHaveProperty(name); + expect(new (root as any)[name]()).toBeInstanceOf(root.KokioError); + } + }); + + it("kokio-sdk/admin exports KokioAdmin, OperationState and the same error classes", () => { + expect(typeof admin.KokioAdmin).toBe("function"); + expect(admin.OperationState).toBeDefined(); + expect(typeof admin.decodeContractRevert).toBe("function"); + for (const name of ERROR_CLASSES) { + expect(admin, name).toHaveProperty(name); + // Both entry points must hand out the same class, or instanceof fails across them. + expect((admin as any)[name]).toBe((root as any)[name]); + } + }); + + it("kokio-sdk/types exports the Settlement enum in contract order", () => { + expect(types.Settlement.DeviceWallet).toBe(0); + expect(types.Settlement.ExternalWallet).toBe(1); + expect(types.Settlement.Fiat).toBe(2); + }); + + it("kokio-sdk/abis exports every contract ABI", () => { + for (const name of [ + "DeviceWallet", + "DeviceWalletFactory", + "ESIMWallet", + "ESIMWalletFactory", + "LazyWalletRegistry", + "P256Verifier", + "Registry", + "RegistryHelper", + "BeaconProxy", + "ProtocolAdmin", + "PaymentAdapter", + ]) { + expect(Array.isArray((abis as any)[name]), name).toBe(true); + } + }); +}); diff --git a/tests/consumer/smartAccount.fork.test.ts b/tests/consumer/smartAccount.fork.test.ts new file mode 100644 index 0000000..62670d6 --- /dev/null +++ b/tests/consumer/smartAccount.fork.test.ts @@ -0,0 +1,77 @@ +import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; +import { hashMessage, type TypedDataDefinition } from "viem"; + +const passkeyGet = vi.hoisted(() => vi.fn()); +vi.mock("react-native-passkey", () => ({ Passkey: { get: passkeyGet } })); + +import { asPasskey } from "./fixtures/passkeyAuthenticator.js"; +import { expectSponsored } from "./fixtures/sponsorship.js"; +import { startForkStack, type ForkStack } from "./fixtures/forkStack.js"; +import { TEST_TAG } from "./fixtures/testLabels.js"; +import { createTestUser, forkTarget } from "./fixtures/user.js"; + +const ERC1271_MAGIC = "0x1626ba7e"; +const MESSAGE = `${TEST_TAG}: sign in`; +const TYPED_DATA: TypedDataDefinition = { + domain: { name: TEST_TAG, version: "1", chainId: 84532 }, + types: { Login: [{ name: "user", type: "string" }] }, + primaryType: "Login", + message: { user: TEST_TAG }, +}; + +// Smart account behaviour an app relies on beyond the purchase flow: what real +// authenticators hand back, and signatures for sign-in style flows. +describe("smart account on a Base Sepolia fork", () => { + let stack: ForkStack; + + beforeAll(async () => { + stack = await startForkStack(); + }, 180_000); + + afterAll(async () => { + await stack?.stop(); + }); + + it("accepts an authenticator signature with a high s", async () => { + const user = await createTestUser(forkTarget(stack), passkeyGet); + passkeyGet.mockImplementation(asPasskey(user.signer, { highS: true })); + + await expectSponsored(user.client, stack.fork.publicClient, () => user.kokio.deviceWallet!.sendUserOperation([])); + }, 120_000); + + it("signs messages and typed data that verify before and after the wallet is deployed", async () => { + const user = await createTestUser(forkTarget(stack), passkeyGet); + const verify = async () => { + const [message, typed] = await Promise.all([ + stack.fork.publicClient.verifyMessage({ + address: user.deviceWallet, message: MESSAGE, signature: await user.account.signMessage({ message: MESSAGE }), + }), + stack.fork.publicClient.verifyTypedData({ + address: user.deviceWallet, ...TYPED_DATA, signature: await user.account.signTypedData(TYPED_DATA), + } as never), + ]); + return { message, typed }; + }; + + // Not deployed yet, so the signature has to carry the deployment (ERC-6492). + expect(await verify()).toEqual({ message: true, typed: true }); + + await expectSponsored(user.client, stack.fork.publicClient, () => user.kokio.deviceWallet!.sendUserOperation([])); + + expect(await verify()).toEqual({ message: true, typed: true }); + const signature = await user.account.signMessage({ message: MESSAGE }); + expect(await user.kokio.deviceWallet!.isValidSignature(hashMessage(MESSAGE), signature)).toBe(ERC1271_MAGIC); + }, 120_000); + + it("refuses a message signature made by another passkey", async () => { + const user = await createTestUser(forkTarget(stack), passkeyGet); + await expectSponsored(user.client, stack.fork.publicClient, () => user.kokio.deviceWallet!.sendUserOperation([])); + + // Creating a second user points the passkey prompt at that user's key, so + // this signature comes from a key the first wallet does not know. + await createTestUser(forkTarget(stack), passkeyGet); + const signature = await user.account.signMessage({ message: MESSAGE }); + + expect(await stack.fork.publicClient.verifyMessage({ address: user.deviceWallet, message: MESSAGE, signature })).toBe(false); + }, 120_000); +}); diff --git a/tests/consumer/userJourney.fork.test.ts b/tests/consumer/userJourney.fork.test.ts new file mode 100644 index 0000000..35002e6 --- /dev/null +++ b/tests/consumer/userJourney.fork.test.ts @@ -0,0 +1,236 @@ +import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; +import { + encodeAbiParameters, erc20Abi, keccak256, maxUint256, stringToHex, type Address, type Hex, +} from "viem"; + +// The passkey is the one thing Node cannot provide. Everything the SDK does with +// the assertion it returns runs as shipped. +const passkeyGet = vi.hoisted(() => vi.fn()); +vi.mock("react-native-passkey", () => ({ Passkey: { get: passkeyGet } })); + +import { ContractRevertError, type Kokio } from "kokio-sdk"; +import { KokioAdmin } from "kokio-sdk/admin"; +import { Registry } from "kokio-sdk/abis"; +import { Settlement, type KokioSmartAccountClient } from "kokio-sdk/types"; + +import { impersonateAdmin } from "../utils/forkChain.js"; +import type { SoftSigner } from "../utils/softP256Signer.js"; +import { expectSponsored } from "./fixtures/sponsorship.js"; +import { startForkStack, type ForkStack } from "./fixtures/forkStack.js"; +import { setTokenBalance } from "./fixtures/tokens.js"; +import { FORK_POLICY_ID, testBytes32 } from "./fixtures/testLabels.js"; +import { createTestUser, forkTarget } from "./fixtures/user.js"; + +const REGISTRY: Address = "0x916b6b554119c789EF3026EDeB0E1Ba741b42A49"; + +// The four things a user does with the app, in order, each as a sponsored user +// operation through the public SDK. Later steps build on the state earlier ones +// leave, so the steps share one fork and run in sequence. +describe("user journey on a Base Sepolia fork", () => { + let stack: ForkStack; + let signer: SoftSigner; + let kokio: Kokio; + let client: KokioSmartAccountClient; + let deviceWallet: Address; + let uid: string; + let salt: bigint; + let eSIMWallet: Address; + let usdc: Address; + + beforeAll(async () => { + stack = await startForkStack(); + ({ signer, kokio, client, deviceWallet, uid, salt } = await createTestUser(forkTarget(stack), passkeyGet)); + }, 180_000); + + afterAll(async () => { + await stack?.stop(); + }); + + it("deploys the device wallet with its first sponsored user operation", async () => { + expect(await kokio.deviceWalletFactory!.getAddress(uid, signer.ownerKey, salt)).toBe(deviceWallet); + expect(await stack.fork.publicClient.getCode({ address: deviceWallet })).toBeUndefined(); + + const fetchSpy = vi.spyOn(globalThis, "fetch"); + await expectSponsored(client, stack.fork.publicClient, () => kokio.deviceWallet!.sendUserOperation([])); + + // The mock paymaster sponsors whatever it is sent, so check the policy went + // out under the key Pimlico reads. + const stubRequests = fetchSpy.mock.calls + .map(([, init]) => JSON.parse(String(init?.body ?? "{}"))) + .filter((body) => body.method === "pm_getPaymasterStubData"); + fetchSpy.mockRestore(); + expect(stubRequests.length).toBeGreaterThan(0); + expect(stubRequests[0].params[3]).toEqual({ sponsorshipPolicyId: FORK_POLICY_ID }); + + expect(await stack.fork.publicClient.getCode({ address: deviceWallet })).toMatch(/^0x[0-9a-f]+$/i); + expect(await kokio.deviceWallet!.getOwner()).toEqual(signer.ownerKey); + expect(await kokio.deviceWallet!.deviceUniqueIdentifier()).toBe(uid); + }, 120_000); + + it("is registered by the backend after the permissionless deploy", async () => { + // createAccount through the EntryPoint cannot write to the registry, so the + // backend records the wallet afterwards (DeviceWalletFactory.postCreateAccount). + const read = () => stack.fork.publicClient.readContract({ + address: REGISTRY, abi: Registry, functionName: "isDeviceWalletValid", args: [deviceWallet], + }); + expect(await read()).toBe(false); + + const { client: adminClient } = await impersonateAdmin(stack.fork); + const hash = await new KokioAdmin(adminClient).deviceWalletFactory.postCreateAccount(deviceWallet, uid, signer.ownerKey, salt); + await stack.fork.publicClient.waitForTransactionReceipt({ hash }); + + expect(await read()).toBe(true); + expect(await kokio.deviceWalletFactory!.deviceWalletInfoAdded(deviceWallet)).toBe(true); + }, 120_000); + + it("deploys and binds an eSIM wallet as the user", async () => { + const predicted = await kokio.eSIMWalletFactory!.getCounterFactualAddress(deviceWallet, ESIM_SALT); + + const { eSIMWalletAddress } = await expectSponsoredResult(() => + kokio.deviceWallet!.deployAndBindESIMWallet(ESIM_SALT)); + + expect(eSIMWalletAddress).toBe(predicted); + eSIMWallet = eSIMWalletAddress; + kokio.setESIMWalletAddress(eSIMWallet); + + expect(await kokio.eSIMWallet!.owner()).toBe(deviceWallet); + expect(await kokio.deviceWallet!.isValidESIMWallet(eSIMWallet)).toBe(true); + expect(await readRegistry("isESIMWalletValid", [eSIMWallet])).toBe(deviceWallet); + // A bind never carries fund access. + expect(await kokio.deviceWallet!.canPullFunds(eSIMWallet)).toBe(false); + }, 120_000); + + it("grants the eSIM wallet access to the device wallet's tokens", async () => { + await expectSponsored(client, stack.fork.publicClient, () => + kokio.deviceWallet!.toggleAccessToFunds(eSIMWallet, true)); + + expect(await kokio.deviceWallet!.canPullFunds(eSIMWallet)).toBe(true); + }, 120_000); + + it("buys a data bundle, pulling the tokens from the device wallet", async () => { + const { token } = await kokio.paymentAdapter!.resolveAsset(USDC); + usdc = token; + const quote = await kokio.paymentAdapter!.quote(USDC, BUNDLE.priceUSDCents); + expect(quote).toBe(5_000_000n); // 500 cents in 6-decimal USDC + + await setTokenBalance(stack.fork, usdc, deviceWallet, 20_000_000n); + const vault = await readRegistry("vault", []) as Address; + const vaultBefore = await balanceOf(usdc, vault); + + await expectSponsored(client, stack.fork.publicClient, () => + kokio.eSIMWallet!.buyDataBundleWithToken(BUNDLE, USDC, quote, REF_1)); + + expect(await balanceOf(usdc, deviceWallet)).toBe(20_000_000n - quote); + expect(await balanceOf(usdc, vault)).toBe(vaultBefore + quote); + expect(await kokio.eSIMWallet!.transactionHistory(0n)).toMatchObject({ + id: BUNDLE.id, + priceUSDCents: BUNDLE.priceUSDCents, + settlement: Settlement.DeviceWallet, + }); + expect(await readRegistry("usedPaymentReferences", [scopedReference(eSIMWallet, REF_1)])).toBe(true); + }, 120_000); + + it("refuses a payment reference the eSIM wallet already spent", async () => { + const quote = await kokio.paymentAdapter!.quote(USDC, BUNDLE.priceUSDCents); + + expect(await revertOf(kokio.eSIMWallet!.buyDataBundleWithToken(BUNDLE, USDC, quote, REF_1))) + .toBe("PaymentReferenceAlreadyUsed"); + }, 120_000); + + it("refuses a price above the cap and a quote above maxAmountIn", async () => { + const quote = await kokio.paymentAdapter!.quote(USDC, BUNDLE.priceUSDCents); + const cap = await readRegistry("defaultPriceCapUSDCents", []) as bigint; + + expect(await revertOf(kokio.eSIMWallet!.buyDataBundleWithToken( + { ...BUNDLE, priceUSDCents: cap + 1n }, USDC, maxUint256, REF_2, + ))).toBe("DataBundlePriceAboveCap"); + + expect(await revertOf(kokio.eSIMWallet!.buyDataBundleWithToken(BUNDLE, USDC, quote - 1n, REF_2))) + .toBe("SettlementAboveMax"); + + expect(await revertOf(kokio.eSIMWallet!.buyDataBundleWithToken(BUNDLE, testBytes32("coin"), quote, REF_2))) + .toBe("AssetNotAllowed"); + }, 120_000); + + it("stops pulling tokens once access is revoked", async () => { + await expectSponsored(client, stack.fork.publicClient, () => + kokio.deviceWallet!.toggleAccessToFunds(eSIMWallet, false)); + expect(await kokio.deviceWallet!.canPullFunds(eSIMWallet)).toBe(false); + + const quote = await kokio.paymentAdapter!.quote(USDC, BUNDLE.priceUSDCents); + expect(await revertOf(kokio.eSIMWallet!.buyDataBundleWithToken(BUNDLE, USDC, quote, REF_2))) + .toBe("FundsAccessRevoked"); + }, 120_000); + + it("buys without pull access by sending the tokens in the same user operation", async () => { + const quote = await kokio.paymentAdapter!.quote(USDC, BUNDLE.priceUSDCents); + const before = await balanceOf(usdc, deviceWallet); + + await expectSponsored(client, stack.fork.publicClient, () => + kokio.eSIMWallet!.buyDataBundleWithTransfer(BUNDLE, USDC, quote, REF_2)); + + expect(await balanceOf(usdc, deviceWallet)).toBe(before - quote); + expect(await balanceOf(usdc, eSIMWallet)).toBe(0n); + expect((await kokio.eSIMWallet!.transactionHistory(1n)).id).toBe(BUNDLE.id); + }, 120_000); + + it("buys with the USDCt test token, the second asset the adapter accepts", async () => { + const { token } = await kokio.paymentAdapter!.resolveAsset(USDCT); + expect(token).not.toBe(usdc); + const quote = await kokio.paymentAdapter!.quote(USDCT, BUNDLE.priceUSDCents); + await setTokenBalance(stack.fork, token, deviceWallet, quote); + const vault = await readRegistry("vault", []) as Address; + const vaultBefore = await balanceOf(token, vault); + + await expectSponsored(client, stack.fork.publicClient, () => + kokio.eSIMWallet!.buyDataBundleWithTransfer(BUNDLE, USDCT, quote, REF_3)); + + expect(await balanceOf(token, deviceWallet)).toBe(0n); + expect(await balanceOf(token, vault)).toBe(vaultBefore + quote); + expect((await kokio.eSIMWallet!.transactionHistory(2n)).id).toBe(BUNDLE.id); + }, 120_000); + + it("deploys, binds and grants access to a second eSIM wallet in one user operation", async () => { + const { eSIMWalletAddress } = await expectSponsoredResult(() => + kokio.deviceWallet!.deployAndBindESIMWallet(ESIM_SALT + 1n, { grantAccessToFunds: true })); + + expect(await kokio.deviceWallet!.isValidESIMWallet(eSIMWalletAddress)).toBe(true); + expect(await kokio.deviceWallet!.canPullFunds(eSIMWalletAddress)).toBe(true); + }, 120_000); + + // Helpers bound to this suite's fork and client. + + const readRegistry = (functionName: string, args: readonly unknown[]) => + stack.fork.publicClient.readContract({ address: REGISTRY, abi: Registry, functionName, args } as never); + + const balanceOf = (token: Address, holder: Address) => + stack.fork.publicClient.readContract({ address: token, abi: erc20Abi, functionName: "balanceOf", args: [holder] }); + + // For helpers that return the user operation hash alongside other values. + const expectSponsoredResult = async (send: () => Promise) => { + let result!: T; + await expectSponsored(client, stack.fork.publicClient, async () => (result = await send()).userOpHash); + return result; + }; +}); + +const ESIM_SALT = 1n; +// Circle's test USDC, and the team's own test token. +const USDC = stringToHex("USDC", { size: 32 }); +const USDCT = stringToHex("USDCt", { size: 32 }); +const BUNDLE = { id: testBytes32("bundle-1"), priceUSDCents: 500n, settlement: Settlement.DeviceWallet }; +const REF_1 = testBytes32("order-1"); +const REF_2 = testBytes32("order-2"); +const REF_3 = testBytes32("order-3"); + +// Registry.usedPaymentReferences is keyed per eSIM wallet (Registry.sol:474). +const scopedReference = (eSIMWallet: Address, ref: Hex) => + keccak256(encodeAbiParameters([{ type: "address" }, { type: "bytes32" }], [eSIMWallet, ref])); + +// The custom error name a rejected user operation carries, as the SDK reports it. +const revertOf = async (pending: Promise): Promise => { + const err = await pending.then(() => undefined, (e: unknown) => e); + if (err === undefined) return "did not revert"; + if (!(err instanceof ContractRevertError)) throw err; + return err.decoded?.errorName ?? `undecoded ${err.data}`; +}; diff --git a/tests/consumer/userJourney.live.test.ts b/tests/consumer/userJourney.live.test.ts new file mode 100644 index 0000000..51ece3a --- /dev/null +++ b/tests/consumer/userJourney.live.test.ts @@ -0,0 +1,87 @@ +import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; +import { stringToHex, type Address } from "viem"; + +const passkeyGet = vi.hoisted(() => vi.fn()); +vi.mock("react-native-passkey", () => ({ Passkey: { get: passkeyGet } })); + +import { ContractRevertError } from "kokio-sdk"; +import { Settlement } from "kokio-sdk/types"; + +import { expectSponsored } from "./fixtures/sponsorship.js"; +import { confirmed, fundFromAdmin, startLiveStack, type LiveStack } from "./fixtures/liveStack.js"; +import { testBytes32 } from "./fixtures/testLabels.js"; +import { createTestUser, type TestUser } from "./fixtures/user.js"; + +// The test token, so live runs never spend Circle USDC. +const USDC = stringToHex("USDCt", { size: 32 }); +// $1.00, so a run costs 1 USDCt, paid to the protocol vault. +const BUNDLE = { id: testBytes32("live-bundle"), priceUSDCents: 100n, settlement: Settlement.DeviceWallet }; +// Unique per run, so a rerun never collides with an earlier purchase. +const REF = testBytes32(`o-${Date.now()}`); +// Hosted RPCs can answer from a node a block behind, so let each write settle. +const SETTLED = { confirmations: 3 }; + +// The user journey on Base Sepolia with the real Pimlico bundler and paymaster. +// Every user operation must be sponsored: the device wallet never holds ETH. +// Sends real testnet transactions. Run with `npm run test:consumer:live`. +describe("user journey on Base Sepolia with Pimlico", () => { + let live: LiveStack; + let user: TestUser; + let eSIMWallet: Address; + + beforeAll(async () => { + live = await startLiveStack(); + user = await createTestUser(live.target, passkeyGet); + }, 120_000); + + afterAll(() => { + // Recorded so a failed run can be looked up on a block explorer. + console.log(`device wallet ${user?.deviceWallet}, eSIM wallet ${eSIMWallet}`); + }); + + it("deploys the device wallet with a sponsored user operation", async () => { + await expectSponsored(user.client, live.publicClient, () => user.kokio.deviceWallet!.sendUserOperation([]), SETTLED); + expect(await live.publicClient.getCode({ address: user.deviceWallet })).toMatch(/^0x[0-9a-f]+$/i); + }, 180_000); + + it("is registered by the backend, signing with its own key over a hosted RPC", async () => { + const hash = await live.admin.deviceWalletFactory.postCreateAccount( + user.deviceWallet, user.uid, user.signer.ownerKey, user.salt, + ); + await confirmed(live, hash); + + expect(await live.admin.registry.isDeviceWalletValid(user.deviceWallet)).toBe(true); + }, 180_000); + + it("deploys, binds and grants access to an eSIM wallet in one sponsored user operation", async () => { + let result!: { userOpHash: `0x${string}`; eSIMWalletAddress: Address }; + await expectSponsored(user.client, live.publicClient, async () => { + result = await user.kokio.deviceWallet!.deployAndBindESIMWallet(1n, { grantAccessToFunds: true }); + return result.userOpHash; + }, SETTLED); + + eSIMWallet = result.eSIMWalletAddress; + user.kokio.setESIMWalletAddress(eSIMWallet); + expect(await user.kokio.deviceWallet!.isValidESIMWallet(eSIMWallet)).toBe(true); + expect(await user.kokio.deviceWallet!.canPullFunds(eSIMWallet)).toBe(true); + }, 180_000); + + it("buys a data bundle with a sponsored user operation", async () => { + const { token } = await user.kokio.paymentAdapter!.resolveAsset(USDC); + const quote = await user.kokio.paymentAdapter!.quote(USDC, BUNDLE.priceUSDCents); + await fundFromAdmin(live, token, user.deviceWallet, quote); + + await expectSponsored(user.client, live.publicClient, () => + user.kokio.eSIMWallet!.buyDataBundleWithToken(BUNDLE, USDC, quote, REF), SETTLED); + + expect((await user.kokio.eSIMWallet!.transactionHistory(0n)).id).toBe(BUNDLE.id); + }, 180_000); + + it("refuses a spent payment reference with a decoded error from Pimlico", async () => { + const quote = await user.kokio.paymentAdapter!.quote(USDC, BUNDLE.priceUSDCents); + const err = await user.kokio.eSIMWallet!.buyDataBundleWithToken(BUNDLE, USDC, quote, REF).catch((e: unknown) => e); + + expect(err).toBeInstanceOf(ContractRevertError); + expect((err as ContractRevertError).decoded?.errorName).toBe("PaymentReferenceAlreadyUsed"); + }, 180_000); +}); diff --git a/tests/integration/README.md b/tests/integration/README.md index f876f20..2c9cb60 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -17,10 +17,9 @@ No keys or funds - read access only. ## Write / UserOp scenario tier - local Base Sepolia fork -`adminFork.integration.test.ts`, `userOpFork.integration.test.ts`, -`protocolAdminFork.integration.test.ts`, -`lazyDeploymentFork.integration.test.ts` and -`erc1271Fork.integration.test.ts` drive real state-changing flows against a +`adminFork.integration.test.ts`, `protocolAdminFork.integration.test.ts`, +`lazyDeploymentFork.integration.test.ts`, `erc1271Fork.integration.test.ts` and +`stubSignatureFork.integration.test.ts` drive real state-changing flows against a local [`anvil`](https://book.getfoundry.sh/anvil/) fork of Base Sepolia. **No private keys and no bundler** are required: @@ -30,8 +29,8 @@ private keys and no bundler** are required: `eSIMWalletAdmin` (anvil `impersonateAccount` + `setBalance`). The timelock suite impersonates the real proposer and guardian the same way, and moves the clock past the delay with `increaseTime`. -- UserOps are submitted by a funded anvil account calling - `EntryPoint.handleOps` directly - no Pimlico, no gas policy. +- User operations sent through a bundler and paymaster are covered by the consumer tier ([../consumer/](../consumer/)). +- Each fork starts from block 46,990,000 on a free port, with its clock moved to the current time. - The passkey signature is produced by a **software** P-256 signer (`tests/utils/softP256Signer.ts`, test-only) that assembles the same `WebAuthnSignature` envelope the native passkey path produces and feeds it @@ -43,8 +42,7 @@ private keys and no bundler** are required: - Foundry installed (`anvil` on `PATH`). Install via [`foundryup`](https://book.getfoundry.sh/getting-started/installation). -- `INTEGRATION=1` (the script sets it). Without Foundry or the flag, the tier - `skipIf`-skips cleanly. +- `INTEGRATION=1` (the script sets it). Without the flag the tier skips. With the flag but no runnable `anvil`, it fails, so a missing Foundry install is not mistaken for a pass. ### Run diff --git a/tests/integration/adminFork.integration.test.ts b/tests/integration/adminFork.integration.test.ts index f7190b5..7d9ca2c 100644 --- a/tests/integration/adminFork.integration.test.ts +++ b/tests/integration/adminFork.integration.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeAll, afterAll, vi } from "vitest"; +import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach, vi } from "vitest"; import { getAddress, getContract, toHex, zeroAddress, zeroHash, type Address, type Hex } from "viem"; import { p256 } from "@noble/curves/nist.js"; @@ -8,7 +8,7 @@ import { p256 } from "@noble/curves/nist.js"; // suites do. `vi.mock` is hoisted above the imports below. vi.mock("react-native-passkey", () => ({ Passkey: {} })); -import { KokioAdmin } from "../../src/admin/config-admin.js"; +import { ContractRevertError, KokioAdmin } from "../../src/admin/config-admin.js"; import { DeviceWalletFactory } from "../../src/abis/index.js"; import { baseSepoliaFactoryAddresses } from "../../src/logic/constants.js"; import type { P256Key } from "../../src/types.js"; @@ -54,7 +54,7 @@ describe.skipIf(!forkAvailable())("KokioAdmin - EOA writes on a Base Sepolia for let ownerSdk: KokioAdmin; beforeAll(async () => { - fork = await startFork(8545); + fork = await startFork(); const impersonatedAdmin = await impersonateAdmin(fork); admin = impersonatedAdmin.admin; adminSdk = new KokioAdmin(impersonatedAdmin.client); @@ -68,6 +68,16 @@ describe.skipIf(!forkAvailable())("KokioAdmin - EOA writes on a Base Sepolia for await fork?.stop(); }); + // Some tests move the admin role, so each starts from the same chain state + // rather than whatever the previous one left. + let snapshot: Hex; + beforeEach(async () => { + snapshot = await fork.testClient.snapshot(); + }); + afterEach(async () => { + await fork.testClient.revert({ id: snapshot }); + }); + it( "createAccount deploys a DeviceWallet at the counterfactual address", async () => { @@ -180,15 +190,13 @@ describe.skipIf(!forkAvailable())("KokioAdmin - EOA writes on a Base Sepolia for const nonOwnerSdk = new KokioAdmin(fork.funded); expect(fork.funded.account?.address).not.toBe(owner); - // The EOA logic sends via a bare-address account (`eth_sendTransaction`), - // so anvil mines the tx and returns a hash even though `onlyOwner` reverts - // it - the access-control failure surfaces as a reverted receipt, not a - // thrown promise. - const hash = (await nonOwnerSdk.registry.requestAdminUpdate( - "0x000000000000000000000000000000000000beef" as Address, - )) as Hex; - const receipt = await fork.publicClient.waitForTransactionReceipt({ hash }); - expect(receipt.status).toBe("reverted"); + // The key signs locally, so viem estimates gas before sending and the + // `onlyOwner` revert comes back as a decoded error with nothing mined. + const err = await nonOwnerSdk.registry + .requestAdminUpdate("0x000000000000000000000000000000000000beef" as Address) + .catch((e: unknown) => e); + expect(err).toBeInstanceOf(ContractRevertError); + expect((err as ContractRevertError).decoded?.errorName).toBe("OwnableUnauthorizedAccount"); }, 60_000, ); diff --git a/tests/integration/erc1271Fork.integration.test.ts b/tests/integration/erc1271Fork.integration.test.ts index 9d6daf1..93991dd 100644 --- a/tests/integration/erc1271Fork.integration.test.ts +++ b/tests/integration/erc1271Fork.integration.test.ts @@ -3,13 +3,11 @@ import { concat, getContract, hashMessage, - hashTypedData, hexToBytes, sliceHex, toHex, type Address, type Hex, - type TypedDataDefinition, } from "viem"; import { isoBase64URL } from "@simplewebauthn/server/helpers"; import { p256 } from "@noble/curves/nist.js"; @@ -27,7 +25,6 @@ import { baseSepoliaFactoryAddresses, CHAIN_ID, SIGNATURE_VALIDITY_SECONDS } fro import { _encodeSignature, _signMessage, - _signTypedData, } from "../../src/logic/account-kit/createSmartAccount.js"; import { forkAvailable, startFork, type Fork } from "../utils/forkChain.js"; import { createSoftSigner, type SoftSigner } from "../utils/softP256Signer.js"; @@ -49,12 +46,6 @@ const asPasskey = (signer: SoftSigner) => async (options: { challenge: string }) }; }; -const typedData: TypedDataDefinition = { - domain: { name: "Kokio", version: "1", chainId: 11155111 }, - types: { Mail: [{ name: "from", type: "address" }, { name: "contents", type: "string" }] }, - primaryType: "Mail", - message: { from: "0x0000000000000000000000000000000000000001", contents: "gm" }, -}; // ERC-1271 message signing against a real device wallet on a local Base Sepolia // fork. The unit tests pin the challenge the SDK builds; this proves the wallet @@ -67,7 +58,7 @@ describe.skipIf(!forkAvailable())("ERC-1271 message signing on a Base Sepolia fo let readWallet: ReturnType; beforeAll(async () => { - fork = await startFork(8549); + fork = await startFork(); signer = createSoftSigner(); passkeyGet.mockImplementation(asPasskey(signer)); @@ -92,19 +83,7 @@ describe.skipIf(!forkAvailable())("ERC-1271 message signing on a Base Sepolia fo const check = (digest: Hex, signature: Hex) => readWallet.read.isValidSignature([digest, signature]) as Promise; - it("the wallet accepts a signature the SDK produced for it", async () => { - const message = "gm from kokio"; - const signature = await _signMessage(message, "cred-id", "kokio.test", CHAIN_ID.BASE_SEPOLIA, wallet); - - expect(await check(hashMessage(message), signature)).toBe(MAGIC_VALUE); - }, 60_000); - - it("the wallet accepts typed data the SDK signed for it", async () => { - const signature = await _signTypedData(typedData, "cred-id", "kokio.test", CHAIN_ID.BASE_SEPOLIA, wallet); - - expect(await check(hashTypedData(typedData), signature)).toBe(MAGIC_VALUE); - }, 60_000); - + // Valid signatures are covered through the public SDK in tests/consumer/smartAccount.fork.test.ts. it("a signature over the bare digest is refused", async () => { // What the SDK sent before it bound the wallet and the chain. The wallet // derives its challenge from the digest rather than reading it, so a diff --git a/tests/integration/lazyDeploymentFork.integration.test.ts b/tests/integration/lazyDeploymentFork.integration.test.ts index e7aa324..100d225 100644 --- a/tests/integration/lazyDeploymentFork.integration.test.ts +++ b/tests/integration/lazyDeploymentFork.integration.test.ts @@ -50,7 +50,7 @@ describe.skipIf(!forkAvailable())("Lazy deployment - pagination on a Base Sepoli let sdk: KokioAdmin; beforeAll(async () => { - fork = await startFork(8548); + fork = await startFork(); sdk = new KokioAdmin((await impersonateAdmin(fork)).client); }, 60_000); @@ -101,7 +101,8 @@ describe.skipIf(!forkAvailable())("Lazy deployment - pagination on a Base Sepoli // contract rather than an address the SDK guessed at. expect(await lazy.read.eSIMWalletsDeployed([device])).toBe(5n); for (const wallet of [result.deviceWallet, ...result.eSIMWallets]) { - expect(await fork.publicClient.getCode({ address: wallet })).not.toBe("0x"); + // getCode answers undefined for an empty address, which would pass a `not.toBe("0x")`. + expect(await fork.publicClient.getCode({ address: wallet })).toMatch(/^0x[0-9a-f]+$/i); } // Running it again finds nothing to do and sends no transaction. diff --git a/tests/integration/protocolAdminFork.integration.test.ts b/tests/integration/protocolAdminFork.integration.test.ts index 04f7b0d..f8138b9 100644 --- a/tests/integration/protocolAdminFork.integration.test.ts +++ b/tests/integration/protocolAdminFork.integration.test.ts @@ -6,7 +6,7 @@ import { getContract, type Address, type Hex } from "viem"; // never signs a passkey, so stub it out of the graph as the other suites do. vi.mock("react-native-passkey", () => ({ Passkey: {} })); -import { KokioAdmin } from "../../src/admin/config-admin.js"; +import { ContractRevertError, KokioAdmin } from "../../src/admin/config-admin.js"; import { Registry } from "../../src/abis/index.js"; import { baseSepoliaFactoryAddresses } from "../../src/logic/constants.js"; import { OperationState } from "../../src/logic/admin/reads/protocolAdmin.reads.js"; @@ -33,9 +33,12 @@ const readRegistry = (fork: Fork) => getContract({ // `writeContract` sends without simulating, so a call the chain refuses still // returns a hash and only shows up as a reverted receipt. Assert on that rather // than on a rejected promise. -const expectReverted = async (fork: Fork, send: Promise) => { - const receipt = await fork.publicClient.waitForTransactionReceipt({ hash: await send }); - expect(receipt.status).toBe("reverted"); +// Every signer here but the impersonated ones signs locally, so viem estimates +// gas first and a refused call comes back as a decoded error, never mined. +const expectRefused = async (send: Promise, errorName: string) => { + const err = await send.catch((e: unknown) => e); + expect(err).toBeInstanceOf(ContractRevertError); + expect((err as ContractRevertError).decoded?.errorName).toBe(errorName); }; // The timelock path against a local Base Sepolia fork: schedule an owner call as @@ -49,7 +52,7 @@ describe.skipIf(!forkAvailable())("ProtocolAdmin - timelock on a Base Sepolia fo let anyoneSdk: KokioAdmin; beforeAll(async () => { - fork = await startFork(8547); + fork = await startFork(); proposerSdk = new KokioAdmin(await impersonate(fork, PROPOSER)); guardianSdk = new KokioAdmin(await impersonate(fork, GUARDIAN)); @@ -72,7 +75,7 @@ describe.skipIf(!forkAvailable())("ProtocolAdmin - timelock on a Base Sepolia fo it("an owner call sent straight from an EOA reverts", async () => { // The whole reason the timelock path exists: the registry's owner is a // contract, so the direct wrapper cannot work on this deployment. - await expectReverted(fork, anyoneSdk.registry.updateVaultAddress(NEW_VAULT)); + await expectRefused(anyoneSdk.registry.updateVaultAddress(NEW_VAULT), "OwnableUnauthorizedAccount"); }, 60_000); it("schedules, waits out the delay, and executes from an account with no role", async () => { @@ -99,7 +102,7 @@ describe.skipIf(!forkAvailable())("ProtocolAdmin - timelock on a Base Sepolia fo expect(await pa.getOperationState(operation.id)).toBe(OperationState.Waiting); // Executing early is rejected outright. - await expectReverted(fork, anyoneSdk.protocolAdmin.executor.execute(operation)); + await expectRefused(anyoneSdk.protocolAdmin.executor.execute(operation), "TimelockUnexpectedOperationState"); await fork.testClient.increaseTime({ seconds: Number(delay) + 1 }); await fork.testClient.mine({ blocks: 1 }); @@ -154,7 +157,7 @@ describe.skipIf(!forkAvailable())("ProtocolAdmin - timelock on a Base Sepolia fo }, 180_000); it("the guardian's instant powers are refused to everyone else", async () => { - await expectReverted(fork, anyoneSdk.protocolAdmin.guardian.disableAdminInstantly(F.REGISTRY)); - await expectReverted(fork, anyoneSdk.protocolAdmin.guardian.unpauseInstantly(F.REGISTRY)); + await expectRefused(anyoneSdk.protocolAdmin.guardian.disableAdminInstantly(F.REGISTRY), "AccessControlUnauthorizedAccount"); + await expectRefused(anyoneSdk.protocolAdmin.guardian.unpauseInstantly(F.REGISTRY), "AccessControlUnauthorizedAccount"); }, 60_000); }); diff --git a/tests/integration/stubSignatureFork.integration.test.ts b/tests/integration/stubSignatureFork.integration.test.ts index 8f3e794..fb3ac67 100644 --- a/tests/integration/stubSignatureFork.integration.test.ts +++ b/tests/integration/stubSignatureFork.integration.test.ts @@ -70,7 +70,7 @@ describe.skipIf(!forkAvailable())("Stub signature validation cost", () => { let fork: Fork; beforeAll(async () => { - fork = await startFork(8550); + fork = await startFork(); }, 60_000); afterAll(async () => { diff --git a/tests/integration/userOpFork.integration.test.ts b/tests/integration/userOpFork.integration.test.ts deleted file mode 100644 index 1752c23..0000000 --- a/tests/integration/userOpFork.integration.test.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { describe, it, expect, beforeAll, afterAll, vi } from "vitest"; -import { - concat, - encodeFunctionData, - getContract, - hashMessage, - encodePacked, - parseEther, - parseGwei, - toHex, - type Address, - type Hex, -} from "viem"; -import { entryPoint08Abi } from "viem/account-abstraction"; - -// Pulled in transitively via `_encodeSignature`; the native passkey module is -// never invoked on this path (the software signer replaces it), so stub it out. -vi.mock("react-native-passkey", () => ({ Passkey: {} })); - -import { DeviceWallet, DeviceWalletFactory } from "../../src/abis/index.js"; -import { baseSepoliaFactoryAddresses } from "../../src/logic/constants.js"; -import { SIGNATURE_VALIDITY_SECONDS } from "../../src/logic/constants.js"; -import { _encodeSignature } from "../../src/logic/account-kit/createSmartAccount.js"; -import { forkAvailable, impersonateAdmin, startFork, type Fork } from "../utils/forkChain.js"; -import { createSoftSigner } from "../utils/softP256Signer.js"; - -const ENTRY_POINT = baseSepoliaFactoryAddresses.ENTRY_POINT as Address; - -// Pack two 16-byte gas values into the EntryPoint bytes32 layout (high ‖ low). -const packGas = (high: bigint, low: bigint): Hex => - concat([toHex(high, { size: 16 }), toHex(low, { size: 16 })]); - -interface PackedUserOperation { - sender: Address; - nonce: bigint; - initCode: Hex; - callData: Hex; - accountGasLimits: Hex; - preVerificationGas: bigint; - gasFees: Hex; - paymasterAndData: Hex; - signature: Hex; -} - -// End-to-end userOp scenario on a local Base Sepolia fork, with no bundler and no -// real keys. A software P-256 signer stands in for the on-device passkey: the -// device wallet is deployed with that key as its owner, a userOp is signed -// through the SDK's real `_encodeSignature` envelope, and a funded anvil EOA -// submits it via `EntryPoint.handleOps`. Success proves the deployed -// `P256Verifier`/`WebAuthn` validation and the `execute` path accept a signature -// the SDK produced. Skips unless INTEGRATION=1 and Foundry (`anvil`) is present. -describe.skipIf(!forkAvailable())("Device-wallet userOp on a Base Sepolia fork", () => { - let fork: Fork; - let admin: Address; - - beforeAll(async () => { - fork = await startFork(8546); - admin = (await impersonateAdmin(fork)).admin; - }, 60_000); - - afterAll(async () => { - await fork?.stop(); - }); - - it( - "verifies a software-P256 signature on-chain and executes a device-wallet call", - async () => { - const signer = createSoftSigner(); - const uid = "fork-userop-p256"; - const salt = 0n; - - const factory = getContract({ - abi: DeviceWalletFactory, - address: baseSepoliaFactoryAddresses.DEVICE_WALLET_FACTORY, - client: { public: fork.publicClient, wallet: fork.funded }, - }); - const entryPoint = getContract({ - abi: entryPoint08Abi, - address: ENTRY_POINT, - client: { public: fork.publicClient, wallet: fork.funded }, - }); - - // Deploy the device wallet owned by the software key. `createAccount` is - // public/payable, so the funded anvil EOA can call it directly. - const sender = (await factory.read.getCounterFactualAddress([signer.ownerKey, uid, salt])) as Address; - const deployHash = await factory.write.createAccount([uid, signer.ownerKey, salt], { value: 0n }); - await fork.publicClient.waitForTransactionReceipt({ hash: deployHash }); - expect(await fork.publicClient.getCode({ address: sender })).not.toBe("0x"); - - // Fund the account's gas (EntryPoint deposit) and its ETH balance (for the - // value it will forward through `execute`). - const depositHash = await entryPoint.write.depositTo([sender], { value: parseEther("1") }); - await fork.publicClient.waitForTransactionReceipt({ hash: depositHash }); - await fork.testClient.setBalance({ address: sender, value: parseEther("1") }); - - // The action the userOp performs: forward 0.01 ETH to a fresh recipient. - const recipient = "0x00000000000000000000000000000000000d00d1" as Address; - const transferValue = parseEther("0.01"); - const callData = encodeFunctionData({ - abi: DeviceWallet, - functionName: "execute", - args: [{ dest: recipient, value: transferValue, data: "0x" }], - }); - - const nonce = (await entryPoint.read.getNonce([sender, 0n])) as bigint; - - const userOp: PackedUserOperation = { - sender, - nonce, - initCode: "0x", - callData, - accountGasLimits: packGas(1_000_000n, 1_000_000n), - preVerificationGas: 1_000_000n, - gasFees: packGas(parseGwei("2"), parseGwei("50")), - paymasterAndData: "0x", - signature: "0x", - }; - - // Hash via the deployed EntryPoint so the digest matches exactly. - const userOpHash = (await entryPoint.read.getUserOpHash([userOp])) as Hex; - - // Reproduce `_signUserOperationHash`'s envelope, swapping only the native - // `_stamp` for the software signer; the SDK's real `_encodeSignature` runs. - const validUntil = Math.floor(Date.now() / 1000) + SIGNATURE_VALIDITY_SECONDS; - const precursor = encodePacked(["uint8", "uint48", "bytes32"], [1, validUntil, userOpHash]); - const payload = hashMessage({ raw: precursor }); - userOp.signature = await _encodeSignature(signer.stamp(payload), validUntil); - - const recipientBefore = await fork.publicClient.getBalance({ address: recipient }); - - const handleHash = await entryPoint.write.handleOps([[userOp], admin]); - const receipt = await fork.publicClient.waitForTransactionReceipt({ hash: handleHash }); - expect(receipt.status).toBe("success"); - - // The EntryPoint reports userOp success (signature verified + call ran)... - const events = await entryPoint.getEvents.UserOperationEvent({}, { - blockHash: receipt.blockHash, - }); - expect(events.length).toBe(1); - expect(events[0].args.success).toBe(true); - - // ...and the on-chain effect landed: the recipient received the forwarded ETH. - const recipientAfter = await fork.publicClient.getBalance({ address: recipient }); - expect(recipientAfter - recipientBefore).toBe(transferValue); - }, - 120_000, - ); -}); diff --git a/tests/logic/account-kit/createSmartAccount.test.ts b/tests/logic/account-kit/createSmartAccount.test.ts index 5505a14..166a43b 100644 --- a/tests/logic/account-kit/createSmartAccount.test.ts +++ b/tests/logic/account-kit/createSmartAccount.test.ts @@ -260,6 +260,63 @@ describe("_stamp (passkey -> WebAuthnSignature)", () => { new Uint8Array(Buffer.from(payload.slice(2), "hex")), ); }); + + it("reads the assertion when Android hands it back as a JSON string", async () => { + passkeyGet.mockResolvedValue(JSON.stringify(mockPasskeyResponse())); + + const result = await _stamp("cred-id", "kokio.test", keccak256("0xabcd")); + expect(result.r).toBe(RAW_R); + expect(result.s).toBe(5n); + expect(result.clientDataJSON).toBe(CLIENT_DATA_JSON); + }); + + it("reads an assertion encoded as padded standard base64", async () => { + passkeyGet.mockResolvedValue({ + response: { + clientDataJSON: Buffer.from(CLIENT_DATA_JSON).toString("base64"), + authenticatorData: Buffer.from(AUTH_DATA).toString("base64"), + signature: Buffer.from(DER_HIGH_S).toString("base64"), + }, + }); + + const result = await _stamp("cred-id", "kokio.test", keccak256("0xabcd")); + expect(result.r).toBe(RAW_R); + expect(result.clientDataJSON).toBe(CLIENT_DATA_JSON); + }); + + it("falls back to typeIndex 0 when clientDataJSON has no compact type field", async () => { + // Valid JSON, but the spacing defeats the substring search. The contract + // then checks the wrong offset, so this assertion cannot verify on chain. + const spaced = '{"type": "webauthn.get","challenge":"AAAA"}'; + const response = mockPasskeyResponse(); + response.response.clientDataJSON = isoBase64URL.fromBuffer(new TextEncoder().encode(spaced)); + passkeyGet.mockResolvedValue(response); + const warn = vi.spyOn(console, "warn").mockImplementation(() => {}); + + const result = await _stamp("cred-id", "kokio.test", keccak256("0xabcd")); + expect(result.typeIndex).toBe(0n); + expect(warn).toHaveBeenCalled(); + warn.mockRestore(); + }); + + it("throws when clientDataJSON carries no challenge", async () => { + const response = mockPasskeyResponse(); + response.response.clientDataJSON = isoBase64URL.fromBuffer(new TextEncoder().encode('{"type":"webauthn.get"}')); + passkeyGet.mockResolvedValue(response); + + await expect(_stamp("cred-id", "kokio.test", keccak256("0xabcd"))).rejects.toThrow(/challenge/); + }); + + it("rethrows when the passkey prompt fails or is cancelled", async () => { + const cancelled = new Error("The operation was cancelled"); + passkeyGet.mockRejectedValue(cancelled); + const log = vi.spyOn(console, "log").mockImplementation(() => {}); + const error = vi.spyOn(console, "error").mockImplementation(() => {}); + + await expect(_stamp("cred-id", "kokio.test", keccak256("0xabcd"))).rejects.toBe(cancelled); + log.mockRestore(); + error.mockRestore(); + }); }); // The two ERC-1271 signers bind the wallet and the chain into the challenge, so diff --git a/tests/logic/admin/adminReads.test.ts b/tests/logic/admin/adminReads.test.ts index f328fdf..238fe0d 100644 --- a/tests/logic/admin/adminReads.test.ts +++ b/tests/logic/admin/adminReads.test.ts @@ -11,6 +11,7 @@ import * as lazyWalletRegistry from "../../../src/logic/admin/reads/lazyWalletRe import * as deviceWallet from "../../../src/logic/admin/reads/deviceWallet.reads.js"; import * as eSIMWallet from "../../../src/logic/admin/reads/eSIMWallet.reads.js"; import * as paymentAdapter from "../../../src/logic/admin/reads/paymentAdapter.reads.js"; +import * as protocolAdmin from "../../../src/logic/admin/reads/protocolAdmin.reads.js"; // --- Fixtures --------------------------------------------------------------- const WALLET = "0x00000000000000000000000000000000000dead1" as Address; @@ -138,6 +139,23 @@ const readCases: Array<{ { label: "paymentAdapter._quote", run: (c) => paymentAdapter._quote(c, ASSET, 1000n), address: F.PAYMENT_ADAPTER, functionName: "quote", args: [ASSET, 1000n] }, { label: "paymentAdapter._usedReferences", run: (c) => paymentAdapter._usedReferences(c, PAYMENT_REFERENCE), address: F.PAYMENT_ADAPTER, functionName: "usedReferences", args: [PAYMENT_REFERENCE] }, { label: "paymentAdapter._upgradeManager", run: (c) => paymentAdapter._upgradeManager(c), address: F.PAYMENT_ADAPTER, functionName: "upgradeManager", args: [] }, + + // protocolAdmin.reads (target = PROTOCOL_ADMIN, the timelock) + { label: "protocolAdmin._getMinDelay", run: (c) => protocolAdmin._getMinDelay(c), address: F.PROTOCOL_ADMIN, functionName: "getMinDelay", args: [] }, + { label: "protocolAdmin._minDelayFloor", run: (c) => protocolAdmin._minDelayFloor(c), address: F.PROTOCOL_ADMIN, functionName: "minDelayFloor", args: [] }, + { label: "protocolAdmin._getOperationState", run: (c) => protocolAdmin._getOperationState(c, HASH), address: F.PROTOCOL_ADMIN, functionName: "getOperationState", args: [HASH] }, + { label: "protocolAdmin._getTimestamp", run: (c) => protocolAdmin._getTimestamp(c, HASH), address: F.PROTOCOL_ADMIN, functionName: "getTimestamp", args: [HASH] }, + { label: "protocolAdmin._isOperation", run: (c) => protocolAdmin._isOperation(c, HASH), address: F.PROTOCOL_ADMIN, functionName: "isOperation", args: [HASH] }, + { label: "protocolAdmin._isOperationPending", run: (c) => protocolAdmin._isOperationPending(c, HASH), address: F.PROTOCOL_ADMIN, functionName: "isOperationPending", args: [HASH] }, + { label: "protocolAdmin._isOperationReady", run: (c) => protocolAdmin._isOperationReady(c, HASH), address: F.PROTOCOL_ADMIN, functionName: "isOperationReady", args: [HASH] }, + { label: "protocolAdmin._isOperationDone", run: (c) => protocolAdmin._isOperationDone(c, HASH), address: F.PROTOCOL_ADMIN, functionName: "isOperationDone", args: [HASH] }, + { label: "protocolAdmin._hasRole", run: (c) => protocolAdmin._hasRole(c, HASH, WALLET), address: F.PROTOCOL_ADMIN, functionName: "hasRole", args: [HASH, WALLET] }, + { label: "protocolAdmin._getRoleAdmin", run: (c) => protocolAdmin._getRoleAdmin(c, HASH), address: F.PROTOCOL_ADMIN, functionName: "getRoleAdmin", args: [HASH] }, + { label: "protocolAdmin._defaultAdminRole", run: (c) => protocolAdmin._defaultAdminRole(c), address: F.PROTOCOL_ADMIN, functionName: "DEFAULT_ADMIN_ROLE", args: [] }, + { label: "protocolAdmin._proposerRole", run: (c) => protocolAdmin._proposerRole(c), address: F.PROTOCOL_ADMIN, functionName: "PROPOSER_ROLE", args: [] }, + { label: "protocolAdmin._cancellerRole", run: (c) => protocolAdmin._cancellerRole(c), address: F.PROTOCOL_ADMIN, functionName: "CANCELLER_ROLE", args: [] }, + { label: "protocolAdmin._executorRole", run: (c) => protocolAdmin._executorRole(c), address: F.PROTOCOL_ADMIN, functionName: "EXECUTOR_ROLE", args: [] }, + { label: "protocolAdmin._guardianRole", run: (c) => protocolAdmin._guardianRole(c), address: F.PROTOCOL_ADMIN, functionName: "GUARDIAN_ROLE", args: [] }, ]; describe("admin readContract calls", () => { diff --git a/tests/logic/admin/adminSubpackages.test.ts b/tests/logic/admin/adminSubpackages.test.ts index 15ff024..fbebf61 100644 --- a/tests/logic/admin/adminSubpackages.test.ts +++ b/tests/logic/admin/adminSubpackages.test.ts @@ -308,8 +308,9 @@ describe("admin-EOA writeContract calls", () => { expect(arg.functionName).toBe(functionName); expect(arg.args).toEqual(args); expect(arg.value).toBe(value); - // EOA account + resolved chain are always threaded through. - expect(arg.account).toBe(EOA); + // The client's own account object is passed, not its address: viem signs + // locally only for a local account, and a bare address goes to eth_sendTransaction. + expect(arg.account).toBe(client.account); expect(arg.chain).toBeDefined(); }); diff --git a/tests/logic/admin/protocolAdmin.test.ts b/tests/logic/admin/protocolAdmin.test.ts index c9e797c..b8e317c 100644 --- a/tests/logic/admin/protocolAdmin.test.ts +++ b/tests/logic/admin/protocolAdmin.test.ts @@ -60,7 +60,7 @@ describe("protocolAdmin schedule", () => { expect(arg.functionName).toBe("schedule"); // The payload targets the registry, the transaction targets the timelock. expect(arg.args).toEqual([F.REGISTRY, 0n, VAULT_PAYLOAD, ZERO32, ZERO32, MIN_DELAY]); - expect(arg.account).toBe(EOA); + expect(arg.account).toBe(client.account); // The returned object carries everything execute has to reproduce. expect(op).toEqual({ @@ -119,6 +119,23 @@ describe("protocolAdmin schedule", () => { expect(op.values).toEqual([0n, 2n]); }); + it("operationIdBatch hashes the calls the way scheduleBatch sends them", async () => { + const client = scheduleClient(); + + await protocolAdmin._operationIdBatch(client, [VAULT_CALL, { ...VAULT_CALL, value: 2n }], { salt: SALT }); + + const read = (client.readContract as ReturnType).mock.calls[0][0]; + expect(read.address).toBe(PA); + expect(read.functionName).toBe("hashOperationBatch"); + expect(read.args).toEqual([ + [F.REGISTRY, F.REGISTRY], + [0n, 2n], + [VAULT_PAYLOAD, VAULT_PAYLOAD], + ZERO32, + SALT, + ]); + }); + it("hashes a batch with hashOperationBatch, not hashOperation", async () => { const client = scheduleClient(); @@ -309,7 +326,7 @@ describe("protocolAdmin direct writes", () => { expect(arg.abi).toBe(ProtocolAdmin); expect(arg.functionName).toBe(functionName); expect(arg.args).toEqual(args); - expect(arg.account).toBe(EOA); + expect(arg.account).toBe(client.account); }); it.each(directCases)("$label throws MISSING_EOA_WALLET without an account", async ({ run }) => { diff --git a/tests/logic/constants.test.ts b/tests/logic/constants.test.ts index c3dd7a9..b00bec5 100644 --- a/tests/logic/constants.test.ts +++ b/tests/logic/constants.test.ts @@ -1,6 +1,7 @@ -import { describe, it, expect } from "vitest"; +import { describe, it, expect, vi } from "vitest"; import { baseSepolia } from "viem/chains"; import { + _chainId, _getChainSpecificConstants, CHAIN_ID, baseSepoliaFactoryAddresses, @@ -40,3 +41,24 @@ describe("_getChainSpecificConstants - unconfigured chains (P1 guard)", () => { ); }); }); + +describe("_chainId", () => { + it("asks each client for its chain id once", async () => { + const client = { getChainId: vi.fn().mockResolvedValue(84532) }; + + const ids = await Promise.all([_chainId(client), _chainId(client), _chainId(client)]); + expect(ids).toEqual([84532, 84532, 84532]); + expect(client.getChainId).toHaveBeenCalledTimes(1); + + const other = { getChainId: vi.fn().mockResolvedValue(8453) }; + expect(await _chainId(other)).toBe(8453); + }); + + it("asks again after a failed lookup", async () => { + const client = { getChainId: vi.fn().mockRejectedValueOnce(new Error("down")).mockResolvedValue(84532) }; + + await expect(_chainId(client)).rejects.toThrow("down"); + expect(await _chainId(client)).toBe(84532); + expect(client.getChainId).toHaveBeenCalledTimes(2); + }); +}); diff --git a/tests/logic/errors.test.ts b/tests/logic/errors.test.ts index f46dd99..5555760 100644 --- a/tests/logic/errors.test.ts +++ b/tests/logic/errors.test.ts @@ -13,7 +13,7 @@ import { decodeContractRevert, toContractRevertError, } from "../../src/logic/errors.js"; -import { DeviceWalletFactory } from "../../src/abis/index.js"; +import { DeviceWalletFactory, PaymentAdapter, ProtocolAdmin } from "../../src/abis/index.js"; describe("typed errors", () => { it("every typed error is a KokioError with a stable code and its own name", () => { @@ -81,6 +81,18 @@ describe("decodeContractRevert", () => { }); }); +describe("decodeContractRevert for errors only ProtocolAdmin or PaymentAdapter define", () => { + it.each([ + [ProtocolAdmin, "AccessControlUnauthorizedAccount", ["0x0000000000000000000000000000000000000001", toHex(1, { size: 32 })]], + [ProtocolAdmin, "TimelockUnexpectedOperationState", [toHex(1, { size: 32 }), toHex(2, { size: 32 })]], + [PaymentAdapter, "AssetNotAllowed", [toHex(3, { size: 32 })]], + [PaymentAdapter, "SettlementNotFunded", [5n, 4n]], + ] as const)("decodes %$", (abi, errorName, args) => { + const data = encodeErrorResult({ abi, errorName, args } as never); + expect(decodeContractRevert(data)?.errorName).toBe(errorName); + }); +}); + describe("ContractRevertError", () => { it("decodes recognised revert data into a readable message", () => { const data = encodeErrorResult({ abi: DeviceWalletFactory, errorName: "FailedCall" }); @@ -116,6 +128,18 @@ describe("toContractRevertError", () => { expect(err?.data).toBe(data); }); + it("decodes the revert a bundler reports while estimating a user operation", () => { + const data = encodeErrorResult({ abi: DeviceWalletFactory, errorName: "FailedCall" }); + // Alto, and Pimlico which runs it, put the data only in the message (code -32521). + const thrown = new BaseError("RPC Request failed.", { + details: `UserOperation reverted during simulation with reason: ${data}`, + }); + + const err = toContractRevertError(thrown); + expect(err?.decoded?.errorName).toBe("FailedCall"); + expect(err?.data).toBe(data); + }); + it("returns null for an error that isn't a viem BaseError", () => { expect(toContractRevertError(new Error("network down"))).toBeNull(); }); diff --git a/tests/logic/utils.test.ts b/tests/logic/utils.test.ts index 9062973..512736b 100644 --- a/tests/logic/utils.test.ts +++ b/tests/logic/utils.test.ts @@ -1,30 +1,18 @@ import { describe, it, expect } from "vitest"; import { _add0x, - _remove0x, _shouldRemoveLeadingZero, _concatUint8Arrays, - base64UrlToBuffer, - decodeClientDataJSON, - hexToArrayBuffer, - parseDEREncodedSignature, - parseSignature, } from "../../src/logic/utils.js"; -describe("_add0x / _remove0x", () => { - it("_add0x prefixes bare hex and leaves 0x-prefixed input intact", () => { +describe("_add0x", () => { + it("prefixes bare hex and leaves 0x-prefixed input intact", () => { expect(_add0x("abcd")).toBe("0xabcd"); expect(_add0x("0xabcd")).toBe("0xabcd"); }); - it("_remove0x strips a leading 0x and is a no-op otherwise", () => { - expect(_remove0x("0xabcd")).toBe("abcd"); - expect(_remove0x("abcd")).toBe("abcd"); - }); - - it("both throw on empty/undefined input", () => { + it("throws on empty/undefined input", () => { expect(() => _add0x("")).toThrow(); - expect(() => _remove0x("")).toThrow(); // @ts-expect-error exercising the runtime null guard expect(() => _add0x(undefined)).toThrow(); }); @@ -48,56 +36,3 @@ describe("_concatUint8Arrays", () => { expect([...out]).toEqual([1, 2, 3, 4, 5]); }); }); - -describe("base64UrlToBuffer / decodeClientDataJSON", () => { - it("round-trips base64url with url-safe chars and missing padding", () => { - const json = '{"type":"webauthn.get","challenge":"abc"}'; - const b64url = Buffer.from(json, "utf-8") - .toString("base64") - .replace(/\+/g, "-") - .replace(/\//g, "_") - .replace(/=+$/, ""); - expect(base64UrlToBuffer(b64url).toString("utf-8")).toBe(json); - expect(decodeClientDataJSON(b64url)).toEqual({ - type: "webauthn.get", - challenge: "abc", - }); - }); -}); - -describe("hexToArrayBuffer", () => { - it("parses hex with and without 0x prefix", () => { - expect([...new Uint8Array(hexToArrayBuffer("0x0102ff"))]).toEqual([1, 2, 255]); - expect([...new Uint8Array(hexToArrayBuffer("0102ff"))]).toEqual([1, 2, 255]); - }); -}); - -describe("DER signature parsing", () => { - // A minimal DER SEQUENCE { INTEGER r, INTEGER s } with r=0x01, s=0x02 - const der = new Uint8Array([0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02]); - - it("parseDEREncodedSignature extracts r and s hex", () => { - expect(parseDEREncodedSignature(der)).toEqual({ r: "01", s: "02" }); - }); - - it("parseSignature splits a 32-byte-integer DER into r and s", () => { - // parseSignature assumes each ASN.1 integer is exactly 32 bytes and just - // concatenates raw r||s. Build a DER with full 32-byte r/s (high bit clear - // so no leading-zero byte is added). - const rBytes = new Uint8Array(32).fill(0); - rBytes[0] = 0x11; - rBytes[31] = 0x01; - const sBytes = new Uint8Array(32).fill(0); - sBytes[0] = 0x22; - sBytes[31] = 0x02; - const der32 = new Uint8Array([ - 0x30, 0x44, - 0x02, 0x20, ...rBytes, - 0x02, 0x20, ...sBytes, - ]); - - const { r, s } = parseSignature(der32); - expect(r).toBe("0x" + Buffer.from(rBytes).toString("hex")); - expect(s).toBe("0x" + Buffer.from(sBytes).toString("hex")); - }); -}); diff --git a/tests/utils/forkChain.ts b/tests/utils/forkChain.ts index d5dadbe..020b7bd 100644 --- a/tests/utils/forkChain.ts +++ b/tests/utils/forkChain.ts @@ -3,6 +3,7 @@ // public endpoint, which is rate limited enough to fail the fork on startup. import "dotenv/config"; import { spawn, spawnSync, type ChildProcess } from "node:child_process"; +import { createServer } from "node:net"; import { createPublicClient, createTestClient, @@ -66,10 +67,29 @@ export const anvilInstalled = (): boolean => { }; /** - * Gate for the whole fork tier: opt-in via INTEGRATION=1 AND Foundry present. - * Keeps `npm test` / CI fully offline and green with no Foundry and no envs. + * Gate for the whole fork tier, opted into with INTEGRATION=1. Keeps `npm test` + * offline. Asking for the tier without Foundry is an error rather than a skip, + * so a run that tested nothing cannot pass as green. */ -export const forkAvailable = (): boolean => process.env.INTEGRATION === "1" && anvilInstalled(); +export const forkAvailable = (): boolean => { + if (process.env.INTEGRATION !== "1") return false; + if (!anvilInstalled()) throw new Error(`INTEGRATION=1 but "${getAnvilBin()}" is not runnable. Install Foundry or set ANVIL_BIN.`); + return true; +}; + +/** Block every fork starts from, so each run sees the same contract state. */ +export const FORK_BLOCK = 46_990_000n; + +/** A port nothing is listening on, so suites never collide. */ +export const freePort = (): Promise => + new Promise((resolve, reject) => { + const server = createServer(); + server.once("error", reject); + server.listen(0, "127.0.0.1", () => { + const { port } = server.address() as { port: number }; + server.close(() => resolve(port)); + }); + }); /** The upstream RPC the fork pulls state from (public endpoint unless overridden). */ export const getForkUpstreamRpc = (): string => process.env.BASE_SEPOLIA_RPC_URL ?? DEFAULT_FORK_RPC; @@ -94,7 +114,8 @@ const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); * id is pinned to 84532 so the SDK treats it as Base Sepolia while serving the * forked state. */ -export const startFork = async (port = 8545): Promise => { +export const startFork = async (port?: number, blockNumber: bigint = FORK_BLOCK): Promise => { + port ??= await freePort(); const upstream = getForkUpstreamRpc(); const rpcUrl = `http://127.0.0.1:${port}`; const publicClient = createPublicClient({ chain: baseSepolia, transport: forkTransport(rpcUrl) }); @@ -108,6 +129,7 @@ export const startFork = async (port = 8545): Promise => { getAnvilBin(), [ "--fork-url", upstream, + "--fork-block-number", String(blockNumber), "--port", String(port), "--chain-id", "84532", "--hardfork", FORK_HARDFORK, @@ -145,6 +167,11 @@ export const startFork = async (port = 8545): Promise => { const testClient = createTestClient({ chain: baseSepolia, mode: "anvil", transport: forkTransport(rpcUrl) }); + // The pinned block is older than the wall clock, while signatures carry a + // wall-clock expiry as they do on a phone. Bring the chain up to now. + await testClient.setNextBlockTimestamp({ timestamp: BigInt(Math.floor(Date.now() / 1000)) }); + await testClient.mine({ blocks: 1 }); + // anvil's first default account, deterministic across runs. const FUNDED_PK = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" as const; const { privateKeyToAccount } = await import("viem/accounts"); diff --git a/tests/utils/mockClient.ts b/tests/utils/mockClient.ts index 1777f40..2539dd2 100644 --- a/tests/utils/mockClient.ts +++ b/tests/utils/mockClient.ts @@ -40,7 +40,12 @@ export const makeMockWalletClient = (opts: { getChainId: async () => chainId, transport: { url }, account: account ? { address: account, type: "json-rpc" } : undefined, - writeContract: vi.fn(async () => (write ? write() : (receipts ? nextHash() : "0xwritehash"))), + // Every write must pass the client's own account object: with a bare address + // viem sends eth_sendTransaction, which a local private key cannot answer. + writeContract: vi.fn(async (arg: { account?: unknown }) => { + if (arg.account !== client.account) throw new Error("writeContract was not given the client's account object"); + return write ? write() : (receipts ? nextHash() : "0xwritehash"); + }), readContract: vi.fn(async ({ functionName }: { functionName: string }) => reads && functionName in reads ? reads[functionName] : readResult), waitForTransactionReceipt: vi.fn(async () => { diff --git a/vitest.config.ts b/vitest.config.ts index c5d70b2..954be7e 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,23 +1,26 @@ import { defineConfig, configDefaults } from "vitest/config"; -// Integration tests (`*.integration.test.ts`) hit live Base Sepolia and are -// opt-in via `npm run test:integration` (which sets INTEGRATION=1). The default -// run stays offline: it includes only the unit tests and excludes the -// integration suffix. Both modes reuse this one config so they share an -// identical transform pipeline. +// Three opt-in tiers share this config so they share one transform pipeline: +// default unit tests only, fully offline +// INTEGRATION=1 `*.integration.test.ts` and `*.fork.test.ts`, local anvil forks +// KOKIO_LIVE=1 `*.live.test.ts`, real Base Sepolia and Pimlico const integration = !!process.env.INTEGRATION; +const live = !!process.env.KOKIO_LIVE; + +const INTEGRATION_FILES = ["tests/**/*.integration.test.ts", "tests/**/*.fork.test.ts"]; +const LIVE_FILES = ["tests/**/*.live.test.ts"]; export default defineConfig({ test: { - // Node environment — the SDK targets the Expo app / backend server, - // but every unit test here runs against mocked clients (no live RPC). + // The SDK targets the Expo app and a Node backend. No test needs a DOM. environment: "node", - include: integration - ? ["tests/**/*.integration.test.ts"] - : ["tests/**/*.test.ts"], - exclude: integration + include: live ? LIVE_FILES : integration ? INTEGRATION_FILES : ["tests/**/*.test.ts"], + exclude: live || integration ? [...configDefaults.exclude] - : [...configDefaults.exclude, "tests/**/*.integration.test.ts"], + : [...configDefaults.exclude, ...INTEGRATION_FILES, ...LIVE_FILES], globals: false, + // The mock paymaster prints every bundler error it relays, including the + // reverts the refusal tests expect. The tests check those errors themselves. + onConsoleLog: (log) => !log.startsWith("JSON.stringify(err):"), }, });