diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/general.md similarity index 87% rename from .github/ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE/general.md index 6bf08bc..a3b6f0e 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/general.md @@ -1,3 +1,11 @@ +--- +name: "General issue" +about: "Use this for bugs, features, or docs changes" +title: "" +labels: [] +assignees: [] +--- + ## I'm submitting a... - [ ] bug report diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e9a08d..9bcd9b0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,11 +15,17 @@ jobs: - name: Set up Node 22.19.0 uses: actions/setup-node@v4 with: - node-version: "22.19.0" - cache: "npm" + node-version: '22.19.0' + cache: 'npm' + registry-url: 'https://registry.npmjs.org' + - name: Install dependencies run: npm clean-install + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Lint code with standard run: npm run lint + - name: Run tests - run: npm test + run: npm test \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..1dae277 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,54 @@ +name: publish + +on: + release: + types: [published] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Node 22.19.0 + uses: actions/setup-node@v4 + with: + node-version: '22.19.0' + cache: 'npm' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: npm clean-install + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Lint code with standard + run: npm run lint + + - name: Run tests + run: npm test + + publish: + needs: test + runs-on: ubuntu-latest + environment: npm-publish + + steps: + - uses: actions/checkout@v3 + + - name: Set up Node 22.19.0 + uses: actions/setup-node@v4 + with: + node-version: '22.19.0' + cache: 'npm' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: npm clean-install + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Publish to npm + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index 289a442..ab8a598 100644 --- a/README.md +++ b/README.md @@ -1 +1,241 @@ -# @wdk/core +# WDK Core + +**WDK** is a simple tool that enables you to manage the WDK wallet and protocol modules through a single object. + +### Modules Managed + +**Wallet Modules** - Add wallet support for any blockchain: +- `@tetherto/wdk-wallet-evm` - Ethereum, Polygon, Arbitrum +- `@tetherto/wdk-wallet-evm-erc4337` - EVM with no gas fees +- `@tetherto/wdk-wallet-ton` - TON blockchain +- `@tetherto/wdk-wallet-ton-gasless` - TON with no gas fees +- `@tetherto/wdk-wallet-btc` - Bitcoin +- `@tetherto/wdk-wallet-tron` - TRON blockchain +- `@tetherto/wdk-wallet-solana` - Solana blockchain + +**Service Modules** - Add swap, bridge, and lending services: +- `@tetherto/wdk-protocol-swap-paraswap-evm` - Token swaps on EVM +- `@tetherto/wdk-protocol-bridge-usdt0-evm` - Bridge tokens between EVM chains +- `@tetherto/wdk-protocol-bridge-usdt0-ton` - Bridge tokens from TON to other chains +- `@tetherto/wdk-protocol-lending-aave-evm` - Lending and borrowing on EVM + +**📚 Full module list and docs:** [docs.wallet.tether.io](https://docs.wallet.tether.io) + +## Features + +- **Module Manager**: Controls and connects all WDK wallet and service modules +- **Wallet Modules**: Works with `@tetherto/wdk-wallet-evm`, `@tetherto/wdk-wallet-evm-erc-4337`, `@tetherto/wdk-wallet-tron` and other wallet packages +- **Service Modules**: Manages `@tetherto/wdk-protocol-bridge-usdt0-evm`, `@tetherto/wdk-protocol-bridge-usdt0-ton` and other service packages +- **One Setup**: Add any WDK module when you need it for any blockchain +- **Simple Control**: Manage all your wallet and service modules in one place + +## How to Install + +```bash +npm install @tetherto/wdk +``` + +## Quick Start + +```typescript +import WDK from '@tetherto/wdk' +import WalletManagerEvm from '@tetherto/wdk-wallet-evm' +import WalletManagerTon from '@tetherto/wdk-wallet-ton' +import ParaswapProtocolEvm from '@tetherto/wdk-protocol-swap-paraswap-evm' +import Usdt0ProtocolTon from '@tetherto/wdk-protocol-bridge-usdt0-ton' + +// Set up WDK with wallets and services +const wdk = new WDK(seed) //seed are your twelve word phrase + .registerWallet('ethereum', WalletManagerEvm, ethereumWalletConfig) + .registerWallet('ton', WalletManagerTon, tonWalletConfig) + .registerProtocol('ethereum', 'paraswap', ParaswapProtocolEvm, paraswapProtocolConfig) + .registerProtocol('ton', 'usdt0', Usdt0ProtocolTon, usdt0ProtocolConfig) + +// Get accounts using different ways +const ethAccount = await wdk.getAccount('ethereum', 3) +const tonAccount = await wdk.getAccountByPath('ton', "1'/2/3") + +// Send transactions directly +const { hash: txHash, fee: txFee } = await ethAccount.sendTransaction(tx) + +// Use swap service +const paraswap = ethAccount.getSwapProtocol('paraswap') +const { hash: swapHash, fee: swapFee } = await paraswap.swap(swapOptions) + +// Use bridge service +const usdt0 = tonAccount.getBridgeProtocol('usdt0') +const { hash: bridgeHash, fee: bridgeFee } = await usdt0.bridge(bridgeOptions) + +// These will throw errors: +// const accountTron = await wdk.getAccount('tron', 5) // no tron wallet added +// const badBridge = accountEth.getBridgeProtocol('usdt0') // no usdt0 for ethereum +// const badSwap = tonAccount.getSwapProtocol('dedust') // no dedust for ton +``` + +## How to Use + +### WDK + +#### Start +```typescript +constructor(seed: string | Uint8Array) +``` + +#### Add Things +- `registerWallet(blockchain: string, wallet: W, config: WalletConfig): WDK` +- `registerProtocol

(blockchain: string, label: string, protocol: P, config: ProtocolConfig): WDK` +- `registerMiddleware(blockchain: string, middleware: MiddlewareFunction): WDK` +- `registerPolicies(policies: Array): WDK` + +#### Get Accounts +- `getAccount(blockchain: string, index?: number): Promise` +- `getAccountByPath(blockchain: string, path: string): Promise` +- `getFeeRates(blockchain: string): Promise` + +#### Other Tools +- `dispose(): void` + +#### Helper Tools +- `getRandomSeedPhrase(): string` +- `isValidSeedPhrase(seedPhrase: string): boolean` + +### Account with Services + +Works with a basic wallet account but adds service management: + +- `registerProtocol

(label: string, protocol: P, config: ProtocolConfig): IWalletAccountWithProtocols` +- `getSwapProtocol(label: string): ISwapProtocol` - Gets the swap service with the given name +- `getBridgeProtocol(label: string): IBridgeProtocol` - Gets the bridge service with the given name +- `getLendingProtocol(label: string): ILendingProtocol` - Gets the lending service with the given name + +## How to Use It + +### Add Many Blockchains +```typescript +const wdk = new WDK(seed) //seed is your twelve word phrase + .registerWallet('ethereum', WalletManagerEvm, ethereumWalletConfig) + .registerWallet('arbitrum', WalletManagerEvm, arbitrumWalletConfig) + .registerWallet('ton', WalletManagerTon, tonWalletConfig) +``` + +### Add Services to One Account +```typescript +const account = await wdk.getAccount('ethereum', 0) +account.registerProtocol('paraswap', ParaswapProtocolEvm, paraswapProtocolConfig) + +const paraswap = account.getSwapProtocol('paraswap') +const { hash, fee } = await paraswap.swap(swapOptions) + +// This will throw an error - no service with this name: +// const uniswap = account.getSwapProtocol('uniswap') +``` + +### Add Extra Tools to Accounts +```typescript +wdk.registerMiddleware('ethereum', async (account) => { + console.log('New account:', await account.getAddress()) +}) +``` + +### Register Policies + +```typescript +wdk.registerPolicies([ + { + name: 'max-transfer-1eth', + method: 'sendTransaction', + evaluate({ method, params }) { + if (method !== 'sendTransaction') return true + return BigInt(params.value ?? 0) <= 10n ** 18n + } + } +]) +``` + +### Wallet-Specific Policy + +```typescript +wdk.registerPolicies([ + { + name: 'ethereum-only-bridge', + target: { blockchain: 'ethereum' }, + method: 'bridge', + evaluate: () => false + } +]) +``` + +### Protocol-Targeted Policy + +```typescript +wdk.registerPolicies([ + { + name: 'swap-max-fee', + target: { + protocol: { blockchain: 'ethereum', label: 'paraswap' } + }, + method: 'swap', + evaluate: () => false + } +]) +``` + +### Multiple Methods + +```typescript +wdk.registerPolicies([ + { + name: 'disable-critical-ops', + target: { blockchain: 'ethereum' }, + method: ['bridge', 'borrow', 'repay'], + evaluate: () => false + } +]) +``` + +### Recipient Whitelist + +```typescript +const allowed = new Set(['0xabc...', '0xdef...']) + +wdk.registerPolicies([ + { + name: 'recipient-whitelist', + method: 'sendTransaction', + evaluate({ params }) { + if (!params?.to) return true + return allowed.has(params.to.toLowerCase()) + } + } +]) +``` + +### Async Policy + +```typescript +wdk.registerPolicies([ + { + name: 'business-hours', + async evaluate() { + const hour = new Date().getUTCHours() + return hour >= 8 && hour < 18 + } + } +]) +``` + +## License + +This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## Support + +For support, please open an issue on the GitHub repository. + +## Learn More + +For full docs, visit [docs.wallet.tether.io](https://docs.wallet.tether.io) diff --git a/bare.js b/bare.js index c50b407..752035f 100644 --- a/bare.js +++ b/bare.js @@ -14,8 +14,8 @@ 'use strict' -import 'bare-wdk-runtime' +import 'bare-node-runtime/global' -export * from './index.js' with { imports: 'bare-wdk-runtime/package' } +export * from './index.js' with { imports: 'bare-node-runtime/imports' } -export { default } from './index.js' with { imports: 'bare-wdk-runtime/package' } +export { default } from './index.js' with { imports: 'bare-node-runtime/imports' } diff --git a/index.js b/index.js index 2bf02b2..315ec13 100644 --- a/index.js +++ b/index.js @@ -21,3 +21,4 @@ /** @typedef {import('./src/wallet-account-with-protocols.js').IWalletAccountWithProtocols} IWalletAccountWithProtocols */ export { default } from './src/wdk-manager.js' +export { PolicyViolationError } from './src/errors' diff --git a/package-lock.json b/package-lock.json index 7d3988d..2ec4473 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { - "name": "@wdk/core", - "version": "1.0.0-beta.2", + "name": "@tetherto/wdk", + "version": "1.0.0-beta.5", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@wdk/core", - "version": "1.0.0-beta.2", + "name": "@tetherto/wdk", + "version": "1.0.0-beta.5", "license": "Apache-2.0", "dependencies": { - "@wdk/wallet": "https://github.com/davi0kprogramsthings/wdk-wallet#develop", - "bare-wdk-runtime": "2.0.0" + "@tetherto/wdk-wallet": "^1.0.0-beta.6", + "bare-node-runtime": "^1.1.4" }, "devDependencies": { "cross-env": "7.0.3", @@ -35,9 +35,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", - "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", "dev": true, "license": "MIT", "engines": { @@ -45,21 +45,21 @@ } }, "node_modules/@babel/core": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", - "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", + "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.4", + "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.4", - "@babel/types": "^7.28.4", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -76,14 +76,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -172,9 +172,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -206,13 +206,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.4" + "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -476,18 +476,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", - "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", + "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.4", + "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4", + "@babel/types": "^7.28.5", "debug": "^4.3.1" }, "engines": { @@ -495,14 +495,14 @@ } }, "node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -516,9 +516,9 @@ "license": "MIT" }, "node_modules/@emnapi/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", - "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", + "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", "dev": true, "license": "MIT", "optional": true, @@ -528,9 +528,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", - "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", "dev": true, "license": "MIT", "optional": true, @@ -569,9 +569,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -621,9 +621,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -1276,6 +1276,16 @@ "@sinonjs/commons": "^3.0.1" } }, + "node_modules/@tetherto/wdk-wallet": { + "version": "1.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@tetherto/wdk-wallet/-/wdk-wallet-1.0.0-beta.6.tgz", + "integrity": "sha512-McEyTlNFysSpUgA8GxjMUp1RPSm2FsxlNB0ecIXWyqS52TEevjS2BRgXw/h7vUaa4gien0x8Dt4eBWf13l56Xw==", + "license": "Apache-2.0", + "dependencies": { + "bare-node-runtime": "^1.1.4", + "bip39": "3.1.0" + } + }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", @@ -1367,13 +1377,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.4.0.tgz", - "integrity": "sha512-gUuVEAK4/u6F9wRLznPUU4WGUacSEBDPoC2TrBkw3GAnOLHBL45QdfHOXp1kJ4ypBGLxTOB+t7NJLpKoC3gznQ==", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.11.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/stack-utils": { @@ -1384,9 +1394,9 @@ "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "dev": true, "license": "MIT", "dependencies": { @@ -1676,27 +1686,6 @@ "win32" ] }, - "node_modules/@wdk/wallet": { - "version": "1.0.0-beta.1", - "resolved": "git+ssh://git@github.com/davi0kprogramsthings/wdk-wallet.git#1ad2bb750b5959f5e44bd224eb6ea37cbd08288f", - "license": "Apache-2.0", - "dependencies": { - "bare-wdk-runtime": "2.0.0", - "bip39": "3.1.0" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -1993,9 +1982,9 @@ } }, "node_modules/b4a": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.1.tgz", - "integrity": "sha512-ZovbrBV0g6JxK5cGUF1Suby1vLfKjv4RWi8IxoaO/Mon8BDD9I21RxjHFtgQ+kskJqLAVyQZly3uMBui+vhc8Q==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", "license": "Apache-2.0", "peerDependencies": { "react-native-b4a": "*" @@ -2114,6 +2103,33 @@ "dev": true, "license": "MIT" }, + "node_modules/bare-abort-controller": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-abort-controller/-/bare-abort-controller-1.0.0.tgz", + "integrity": "sha512-RSUPsS16TC0EfqfjZUlQwLAtFCUUl7NA0CYaE4/Sl9ExFx3q0WIogBHmW5Zn16NRZUHDJqEffmtnvIyw6LFUjA==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/bare-addon-resolve": { + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.9.6.tgz", + "integrity": "sha512-hvOQY1zDK6u0rSr27T6QlULoVLwi8J2k8HHHJlxSfT7XQdQ/7bsS+AnjYkHtu/TkL+gm3aMXAKucJkJAbrDG/g==", + "license": "Apache-2.0", + "dependencies": { + "bare-module-resolve": "^1.10.0", + "bare-semver": "^1.0.0" + }, + "peerDependencies": { + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-url": { + "optional": true + } + } + }, "node_modules/bare-ansi-escapes": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/bare-ansi-escapes/-/bare-ansi-escapes-2.2.3.tgz", @@ -2132,27 +2148,75 @@ } }, "node_modules/bare-assert": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bare-assert/-/bare-assert-1.1.0.tgz", - "integrity": "sha512-G/oDyI81+FR4Qri6nS+b4XRoh8wjuBMua3R69kIytSdXsl+VD3Qo95im2D+0cL5wXJ5kgxmdUJ0n4nYAA73yNg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bare-assert/-/bare-assert-1.2.0.tgz", + "integrity": "sha512-c6uvgvTJBspTDxtVnPgrBKmLgcpW3Fp72NVKDLg6oT4QjQbhGtvrkHMhGYMK1sh4vjBHOBmuUalyt9hSzV37fQ==", "license": "Apache-2.0", "dependencies": { "bare-inspect": "^3.1.2" } }, + "node_modules/bare-async-hooks": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/bare-async-hooks/-/bare-async-hooks-0.0.0.tgz", + "integrity": "sha512-xNfGwUobaomCGMGAqohAekS3uMCj+4tvI4AoOaJnO7NfpN+dvFdkC5xkeQtmZzs2vxf2TR5J6i5FDd1ImCZERw==", + "license": "Apache-2.0" + }, "node_modules/bare-buffer": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/bare-buffer/-/bare-buffer-3.3.1.tgz", - "integrity": "sha512-BjsDDn3MUhl+D1774DKKfWiM38PTuw3zTEmzDb8IgSK6j9vN5GMOG/ldiJN1lnCWwFEp0OaMl7hfUsep+6cWCA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/bare-buffer/-/bare-buffer-3.4.2.tgz", + "integrity": "sha512-e3s+hh+7KsEPA9Gg1q0e6vkvMaO+vyARkDrU/LPfojg4Q2G5wj+fjr8YDFELibSokECMhJmzhJMRwPRKVqPh+g==", "license": "Apache-2.0", "engines": { "bare": ">=1.20.0" } }, + "node_modules/bare-bundle": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/bare-bundle/-/bare-bundle-1.10.0.tgz", + "integrity": "sha512-4LVlnJAHr00Hh6Vu6ZUJS38rcEtJT3b3vChXSsBsJ2mk1TN0lQ+gzd+Dw5L0aV7uqDZv84smuwW+O02X7PfDlw==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-buffer": "*", + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-url": { + "optional": true + } + } + }, + "node_modules/bare-channel": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bare-channel/-/bare-channel-5.2.2.tgz", + "integrity": "sha512-lM5nPZKV4mWB0djziPr+FaLeoaMmNeUjlbtRZ84ad0FbZEWjlrEIj3ShufHx5xXMXgot0GZk+iLtubCYZVoSNQ==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.0.0", + "bare-stream": "^2.7.0", + "bare-structured-clone": "^1.4.0" + }, + "engines": { + "bare": ">=1.7.0" + } + }, + "node_modules/bare-console": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/bare-console/-/bare-console-6.0.2.tgz", + "integrity": "sha512-GzU+lAa/vCQ3ksC41fCst1nm9B9u4zpyYw6UhjeOlGjbdTWFecQsoPmvW/Md8nQCbHcjRXzendtaLW8z02aFqA==", + "license": "Apache-2.0", + "dependencies": { + "bare-hrtime": "^2.0.0", + "bare-logger": "^2.0.0" + } + }, "node_modules/bare-crypto": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/bare-crypto/-/bare-crypto-1.11.2.tgz", - "integrity": "sha512-frwW8a5ZeIzkg6jyjJ5g+yQQmsWa5DhLnRr92fsKQx00dA3aWU7zDLFg7Jlr5xNCvNhYElLI3Zd6u8cPj79ZOw==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/bare-crypto/-/bare-crypto-1.12.0.tgz", + "integrity": "sha512-GLeZOS2RQkEawVNPvBKmVZQWwSs4jLhculTvuOfLdP+RTMN1Gv3pz+oI9fcQj7/LE2QJM4cPOHfx4u0izBaTHA==", "license": "Apache-2.0", "dependencies": { "bare-stream": "^2.6.3" @@ -2175,6 +2239,22 @@ "bare-os": "^3.0.1" } }, + "node_modules/bare-dgram": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bare-dgram/-/bare-dgram-1.0.1.tgz", + "integrity": "sha512-EdsyRErrkWgN8fENdrDdXFEE9HAuJ/m6ehXz13fVj9JhdCaLWIA+L8o5aYNRLt66x08RlyG2vbrRAZoxGfcdlg==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.5.0", + "udx-native": "^1.11.2" + } + }, + "node_modules/bare-diagnostics-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bare-diagnostics-channel/-/bare-diagnostics-channel-1.1.0.tgz", + "integrity": "sha512-Reu+EQo+eLpB+a5p8UykFEdXndFaRaSgKV38uAMh/qhE2eTeJcdwAwo74hKYyeN8GD3DIFqC9ZlM4bnDc03CIg==", + "license": "Apache-2.0" + }, "node_modules/bare-dns": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/bare-dns/-/bare-dns-2.1.4.tgz", @@ -2208,15 +2288,23 @@ } }, "node_modules/bare-events": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.1.tgz", - "integrity": "sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g==", - "license": "Apache-2.0" + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } }, "node_modules/bare-fetch": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-fetch/-/bare-fetch-2.5.0.tgz", - "integrity": "sha512-2f/mx0hw4CDH2yX2cT7tVZGPnXcUswZCYu/EY72hHfbAipZJwZtDl8f3DsXJG+yXyPBNw3TNPicMbYPpfuaIfw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/bare-fetch/-/bare-fetch-2.5.1.tgz", + "integrity": "sha512-BdJie1S9y3TW0pzF6Q/dP95QDjlUPXexiJWSnKFIM/OHID6ITJk2XEQQ25rsGqwLqxQ4felfGkj13mC/ao27mg==", "license": "Apache-2.0", "dependencies": { "bare-form-data": "^1.1.3", @@ -2257,9 +2345,9 @@ } }, "node_modules/bare-fs": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.4.4.tgz", - "integrity": "sha512-Q8yxM1eLhJfuM7KXVP3zjhBvtMJCYRByoTT+wHXjpdMELv0xICFJX+1w4c7csa+WZEOsq4ItJ4RGwvzid6m/dw==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.2.tgz", + "integrity": "sha512-veTnRzkb6aPHOvSKIOy60KzURfBdUflr5VReI+NSaPL6xf+XLdONQgZgpYvUuZLVQ8dCqxpBAudaOM1+KpAUxw==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.5.4", @@ -2281,20 +2369,27 @@ } }, "node_modules/bare-hrtime": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bare-hrtime/-/bare-hrtime-2.1.0.tgz", - "integrity": "sha512-Y72D/5k/q7ViBofHLL4XPjBBSp8/ClzL+Cr8na9uozIPAfxFZu8LxuMyL2d6MV/Ogmjn7zPJpM1NDzKSl6BT6w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bare-hrtime/-/bare-hrtime-2.1.1.tgz", + "integrity": "sha512-VMb3tHo05gsnbu3OXTmkDiwTjMlOsbQmKoysKqKEyR09m77TuDrYFbj3Q5GGk10dAKsUHrnXmwCaeJqzVpB5ZA==", + "license": "Apache-2.0" + }, + "node_modules/bare-http-parser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bare-http-parser/-/bare-http-parser-1.0.1.tgz", + "integrity": "sha512-A3LTDTcELcmNJ3g5liIaS038v/BQxOhA9cjhBESn7eoV7QCuMoIRBKLDadDe08flxyLbxI2f+1l2MZ/5+HnKPA==", "license": "Apache-2.0" }, "node_modules/bare-http1": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/bare-http1/-/bare-http1-4.0.4.tgz", - "integrity": "sha512-QDevXl9l1as1Xl3tXvcUna6cpySpmaQHL3lNnB60+ps46Rn7wTVfiZA9CLdaPzVgsz6Oz7IfIS7xdquBDldAdQ==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/bare-http1/-/bare-http1-4.1.6.tgz", + "integrity": "sha512-IbQZYJZDB+0sriMTH7sW/ygO+mfSm+d5H/qr4IUhKVH4kiGwADw3/rmSIGAnkhppS0kehbypjpmII54nBbkaNg==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.6.0", + "bare-http-parser": "^1.0.0", "bare-stream": "^2.3.0", - "bare-tcp": "^2.0.3" + "bare-tcp": "^2.2.0" }, "peerDependencies": { "bare-buffer": "*", @@ -2310,20 +2405,20 @@ } }, "node_modules/bare-https": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bare-https/-/bare-https-2.0.0.tgz", - "integrity": "sha512-qmjNZmYQ4nn+k3CLlxVyOqWYamdBPqE7psR5/lFWG39fskAR4C2h29d1Ka5BeWOGDAWhXImFIwZUxwCE/7xeLA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bare-https/-/bare-https-2.1.1.tgz", + "integrity": "sha512-1yamjW5TIPBoiwRDGVrTLhbsT8sWKTpDCGiNrJylVFUJD29rwhwrBud9KU/Xe1fWuVcefeRjKoyd2ztFVDv+Sw==", "license": "Apache-2.0", "dependencies": { "bare-http1": "^4.0.0", - "bare-tcp": "^2.0.0", + "bare-tcp": "^2.2.0", "bare-tls": "^2.0.0" } }, "node_modules/bare-inspect": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bare-inspect/-/bare-inspect-3.1.2.tgz", - "integrity": "sha512-K0JmCV0q34SySELz5QiY6BK4vBQ0jmywkCj3Iw6jIh53niN5fZUOPmAVZy0k9RrylylwWaiiVMWenzDD/yvo3A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/bare-inspect/-/bare-inspect-3.1.4.tgz", + "integrity": "sha512-jfW5KRA84o3REpI6Vr4nbvMn+hqVAw8GU1mMdRwUsY5yJovQamxYeKGVKGqdzs+8ZbG4jRzGUXP/3Ji/DnqfPg==", "license": "Apache-2.0", "dependencies": { "bare-ansi-escapes": "^2.1.0", @@ -2333,10 +2428,124 @@ "bare": ">=1.18.0" } }, + "node_modules/bare-inspector": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bare-inspector/-/bare-inspector-5.0.0.tgz", + "integrity": "sha512-blObRFPBK6yn0/wZbrRgkGcOuLUQUYVvkKbsEp5p3bWJB+uNrAh+qUqOijQHS6mZjGvyGCE86VERp3EiUR2TyA==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.1.0", + "bare-http1": "^4.0.0", + "bare-stream": "^2.0.0", + "bare-url": "^2.0.0", + "bare-ws": "^2.0.0" + }, + "engines": { + "bare": ">=1.2.0" + }, + "peerDependencies": { + "bare-tcp": "*" + }, + "peerDependenciesMeta": { + "bare-tcp": { + "optional": true + } + } + }, + "node_modules/bare-logger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bare-logger/-/bare-logger-2.0.0.tgz", + "integrity": "sha512-Oc/jYOFVXnNtIp+BLttGBnOmJU0ved1/R2uUZZNW6VXXP0f6N5v5+tc2sJan7p21VMDPvKCHV+CyUO3QL9lkaA==", + "license": "Apache-2.0", + "dependencies": { + "bare-format": "^1.0.0" + } + }, + "node_modules/bare-module": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-6.1.2.tgz", + "integrity": "sha512-n/M++oHgq8KxIECboY2o9zJ4lDMRmMD2EXO90Iip8GJuS80x+Z0McCwC8dTwUkQrWG5KGuz8MpmoZitfyLQJrQ==", + "license": "Apache-2.0", + "dependencies": { + "bare-bundle": "^1.3.0", + "bare-module-lexer": "^1.0.0", + "bare-module-resolve": "^1.8.0", + "bare-path": "^3.0.0", + "bare-url": "^2.0.1" + }, + "engines": { + "bare": ">=1.23.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-module-lexer": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.4.7.tgz", + "integrity": "sha512-0klU4eMsjh/wcxi8FdHmNom2j2F4kmkXOhyJFL9qTaSFp2lE3m6BtbKgMHY8R5miqC9r8/IfA8wzXnC5Os14WA==", + "license": "Apache-2.0", + "dependencies": { + "require-addon": "^1.0.2" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-module-resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.12.0.tgz", + "integrity": "sha512-JrzrqlC3Tds0iKRwQs8xIIJ+FRieKA9ll0jaqpotDLZtjJPVevzRoeuUYZ5GIo1t1z7/pIRdk85Q3i/2xQLfEQ==", + "license": "Apache-2.0", + "dependencies": { + "bare-semver": "^1.0.0" + }, + "peerDependencies": { + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-url": { + "optional": true + } + } + }, + "node_modules/bare-module-traverse": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/bare-module-traverse/-/bare-module-traverse-1.8.1.tgz", + "integrity": "sha512-bIcnOkA0yqmmRZuIjO156iLvJidIeERCuocSP/dqbtmGeBd79T5d1qumdbGnZU0OFwubDpYHOorFRBBId1t2Ew==", + "license": "Apache-2.0", + "dependencies": { + "bare-addon-resolve": "^1.5.0", + "bare-module-lexer": "^1.4.0", + "bare-module-resolve": "^1.7.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-url": { + "optional": true + } + } + }, "node_modules/bare-net": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bare-net/-/bare-net-2.0.2.tgz", - "integrity": "sha512-+YCNhd2JHVXNieydwNGg7NGbYcoHBPZlVHm9rzzXUm+ZZHv8VcEamutG6NYLdSpixzQ0k/Vj8/GzMRDEgWBLDQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bare-net/-/bare-net-2.2.0.tgz", + "integrity": "sha512-UF7cAbHsGE+H6uEqWF5IULBow1x58chZz4g3ALgHtv7wZsFcCbRDt0JKWEumf5Oma3QWS1Q6aLi0Rpll8RElMg==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.2.2", @@ -2345,6 +2554,51 @@ "bare-tcp": "^2.0.0" } }, + "node_modules/bare-node-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bare-node-runtime/-/bare-node-runtime-1.1.4.tgz", + "integrity": "sha512-Scer2k81VcuTsPmyEX/PCiFqvLZvVNvrmnHCgU/l5/7BM+m9W1wy+oaLkWnU1r33UTHL+Cmxoe0l5HtOgybZOQ==", + "license": "Apache-2.0", + "dependencies": { + "bare-abort-controller": "^1.0.0", + "bare-assert": "^1.1.0", + "bare-async-hooks": "^0.0.0", + "bare-buffer": "^3.3.1", + "bare-console": "^6.0.1", + "bare-crypto": "^1.11.2", + "bare-dgram": "^1.0.1", + "bare-diagnostics-channel": "^1.1.0", + "bare-dns": "^2.1.4", + "bare-events": "^2.7.0", + "bare-fetch": "^2.5.0", + "bare-fs": "^4.2.3", + "bare-http1": "^4.0.4", + "bare-https": "^2.0.0", + "bare-inspector": "^5.0.0", + "bare-module": "^6.1.2", + "bare-net": "^2.0.2", + "bare-os": "^3.6.2", + "bare-path": "^3.0.0", + "bare-performance": "^1.1.0", + "bare-process": "^4.2.1", + "bare-punycode": "^0.0.0", + "bare-querystring": "^1.0.0", + "bare-readline": "^1.1.0", + "bare-repl": "^6.0.1", + "bare-stream": "^2.7.0", + "bare-string-decoder": "^1.0.0", + "bare-subprocess": "^5.1.1", + "bare-timers": "^3.0.3", + "bare-tls": "^2.1.3", + "bare-tty": "^5.0.3", + "bare-url": "^2.2.2", + "bare-utils": "^1.5.1", + "bare-v8": "^1.0.1", + "bare-vm": "^1.0.0", + "bare-worker": "^4.0.0", + "bare-zlib": "^1.3.1" + } + }, "node_modules/bare-os": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", @@ -2363,10 +2617,16 @@ "bare-os": "^3.0.1" } }, + "node_modules/bare-performance": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bare-performance/-/bare-performance-1.3.0.tgz", + "integrity": "sha512-ITlHSQwsnJSPjpagTtPo043LRkFgcrl9SgPsVUBXZvTeGWuNLUfMRwmwAS+35i8qnIEinySoLxwhVoJNZAIF2g==", + "license": "Apache-2.0" + }, "node_modules/bare-pipe": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-4.0.7.tgz", - "integrity": "sha512-y8C6MWpr6EnzUJ1naE04VNTwM1AW3e6abkEDxgQkcTUVPPpHijxld1zpPT1RjWdPuA0TEc8UvEgMtWomnl5X9A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-4.1.2.tgz", + "integrity": "sha512-btXtZLlABEDRp50cfLj9iweISqAJSNMCjeq5v0v9tBY2a7zSSqmfa2ZoE1ki2qxAvubagLUqw6VDifpsuI/qmg==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.0.0", @@ -2377,9 +2637,9 @@ } }, "node_modules/bare-process": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.2.1.tgz", - "integrity": "sha512-wcmyQWTHxd2xRgeKUSY46ofmuEAJ9CLo/6swJTHOZFPYpBShMWNPVI2Ba8o0n/X/YE4as99M28x37saWZ1L1vQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.2.2.tgz", + "integrity": "sha512-ikzEw+HGLB+2lS/WLVEsqi8BXBwzleG3n7DYI0v6/YNklvNabOIGlLd1dof+7Jw5ob4jsBRPtyflweVahY7rFA==", "license": "Apache-2.0", "dependencies": { "bare-env": "^3.0.0", @@ -2391,10 +2651,66 @@ "bare-tty": "^5.0.0" } }, + "node_modules/bare-punycode": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/bare-punycode/-/bare-punycode-0.0.0.tgz", + "integrity": "sha512-PC2Y6mGLytZPJCB9M7CvO5Zb6uWYVUZ+5t3L6vePFuFM6tdC6SsQ+sIsuf0Sa6LHBoWURX7I9yMMbPXMv7TIdQ==", + "license": "Apache-2.0", + "dependencies": { + "punycode": "^2.3.1" + } + }, + "node_modules/bare-querystring": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-querystring/-/bare-querystring-1.0.0.tgz", + "integrity": "sha512-Kbqdjd4f1MxMtutXzraEKIXqXRfq9uWLwzUT5bLUh9TCiPznY9l6vHc4BUPNIa13DyH1VAlPy3iOxHzhqV2quQ==", + "license": "Apache-2.0" + }, + "node_modules/bare-readline": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bare-readline/-/bare-readline-1.2.0.tgz", + "integrity": "sha512-cHT2Q2tLHUHOJMHC2Q+UZxBF3j7aoI65/lWOgXUIm8r65dJV3dzIC06PQx8aLOxH4AWk1B5wVEF+cWnS4tkEtw==", + "license": "Apache-2.0", + "dependencies": { + "bare-ansi-escapes": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-realm": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/bare-realm/-/bare-realm-1.0.8.tgz", + "integrity": "sha512-WvJXxwdmdOawkgtMRVKo5nsKKREA/UtevZMq9bT1HNRPPNfdOhLsV5peTEfHxGO5w6/UIMyRPkVtF6k4xYX7XA==", + "license": "Apache-2.0", + "engines": { + "bare": ">=1.5.0" + } + }, + "node_modules/bare-repl": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/bare-repl/-/bare-repl-6.0.1.tgz", + "integrity": "sha512-dVPUM1UJX2nWTDY3omvrgLeC7IJy3hClxblAWf+dkegz8fh/F9tMs+sB5KCpeBSZ4qvAQv92C+XDtlePqE5sdQ==", + "license": "Apache-2.0", + "dependencies": { + "bare-inspect": "^3.0.0", + "bare-module": "^6.0.1", + "bare-os": "^3.0.1", + "bare-path": "^3.0.0", + "bare-pipe": "^4.0.0", + "bare-readline": "^1.0.0", + "bare-stream": "^2.0.0", + "bare-tty": "^5.0.0" + } + }, + "node_modules/bare-semver": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.2.tgz", + "integrity": "sha512-ESVaN2nzWhcI5tf3Zzcq9aqCZ676VWzqw07eEZ0qxAcEOAFYBa0pWq8sK34OQeHLY3JsfKXZS9mDyzyxGjeLzA==", + "license": "Apache-2.0" + }, "node_modules/bare-signals": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.0.4.tgz", - "integrity": "sha512-RMzSHBvuxKzN7XXO0e2FXSXIjmj7nSeSXNW4jkwI6vCBkfsGwulhGAvLKcmbmQDH37c85y/NoDIPKMHqGnJskw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.2.0.tgz", + "integrity": "sha512-fNHMOdQIlYuTvMB3Oh9Apk99hLKn351+Ir8vz+khiPTcOqIyGG4uWWjdLTzxWdYGsA0eT+We3y0K74hjj2nq7A==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.5.3", @@ -2425,10 +2741,76 @@ } } }, + "node_modules/bare-string-decoder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-string-decoder/-/bare-string-decoder-1.0.0.tgz", + "integrity": "sha512-FjFvfHo88U7borNQSj9ijP2JTb1asqY6K28OZrix4dF9iZf5D2wi1+99CgLlHT3HtYqdwxRhDAiKu8rVstt5rQ==", + "license": "Apache-2.0", + "dependencies": { + "text-decoder": "^1.2.3" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-structured-clone": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/bare-structured-clone/-/bare-structured-clone-1.5.2.tgz", + "integrity": "sha512-V5yevE00wUcmPGgk/O+bsEmuMRGRkwMW1Fncbl8cjH/Eu0+7g0oZSbN7oVGi19c8df9dn25NYymC0v03VVN70w==", + "license": "Apache-2.0", + "dependencies": { + "bare-type": "^1.1.0", + "compact-encoding": "^2.15.0" + }, + "engines": { + "bare": ">=1.2.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-url": { + "optional": true + } + } + }, + "node_modules/bare-subprocess": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-5.2.2.tgz", + "integrity": "sha512-L6oXgQ1aWs25RtG5Ky0bDD06p3RAcVVrDDMWb1DfXpHtyEWxamcyIWUbSykxMTWrpLlmSj6ytbb6yoKehGFfmw==", + "license": "Apache-2.0", + "dependencies": { + "bare-env": "^3.0.0", + "bare-events": "^2.5.4", + "bare-os": "^3.0.1", + "bare-pipe": "^4.0.0", + "bare-url": "^2.2.2" + }, + "engines": { + "bare": ">=1.7.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, "node_modules/bare-tcp": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/bare-tcp/-/bare-tcp-2.0.9.tgz", - "integrity": "sha512-9pxbeUmAgoLitQJNe/gebVM3erWnDq2rvT07CCLUO/bgylbJbCQ8TqyUpnyDhjL2wOtOA5VhcGUkQ0djRGbSjg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-tcp/-/bare-tcp-2.2.2.tgz", + "integrity": "sha512-bYnw1AhzGlfLOD4nTceUXkhhgznZKvDuwjX1Au0VWaVitwqG40oaTvvhEQVCcK3FEwjRTiukUzHnAFsYXUI+3Q==", "license": "Apache-2.0", "dependencies": { "bare-dns": "^2.0.4", @@ -2439,10 +2821,38 @@ "bare": ">=1.16.0" } }, + "node_modules/bare-thread": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/bare-thread/-/bare-thread-1.1.3.tgz", + "integrity": "sha512-XzvgR8ohcOUw7BUepWUlnnAXnQ1LYFpRyTs0C/FG4uq2DA+0gQn5bZSFlSw3XvyB++rhxH0RjmhOy9oyW9q+hw==", + "license": "Apache-2.0", + "dependencies": { + "bare-bundle": "^1.9.0", + "bare-module-resolve": "^1.11.2", + "bare-module-traverse": "^1.7.2" + } + }, + "node_modules/bare-timers": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/bare-timers/-/bare-timers-3.2.0.tgz", + "integrity": "sha512-pBeQu+mUJzT5en5kxA6C6lJuu/9pcIcGhlqbVXXn61CETzRs9vepOMS3hXl82vFlsg3/ggtG36Q+7OZ4IP2MPw==", + "license": "Apache-2.0", + "engines": { + "bare": ">=1.7.0" + }, + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, "node_modules/bare-tls": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-tls/-/bare-tls-2.1.3.tgz", - "integrity": "sha512-axe4pw4n+RyNt+8ld11fwddkfcl0kqgVVf4nOYoJvTxT0MwbMdFIauNzvwcQtFiZ8Pqj+0T4G6yabRQj5IFG3w==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/bare-tls/-/bare-tls-2.1.5.tgz", + "integrity": "sha512-ouc6RqjizIRsUQJcboUI6GiIvwUr30F9xTPzyWFrDpkA1iDsWitLC/mSHjeVXU1H58rvFvnH1xENY8vhJH5e6A==", "license": "Apache-2.0", "dependencies": { "bare-net": "^2.0.1", @@ -2467,18 +2877,18 @@ } }, "node_modules/bare-type": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/bare-type/-/bare-type-1.0.8.tgz", - "integrity": "sha512-7kKAjr5DziSehRe13OTRvsw74/BKgLcECZK37F8J1gnarNLZ1qwZMryC80JT+XryAqn1+vvTEJEBwgT6vhXqiQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bare-type/-/bare-type-1.1.0.tgz", + "integrity": "sha512-LdtnnEEYldOc87Dr4GpsKnStStZk3zfgoEMXy8yvEZkXrcCv9RtYDrUYWFsBQHtaB0s1EUWmcvS6XmEZYIj3Bw==", "license": "Apache-2.0", "engines": { "bare": ">=1.2.0" } }, "node_modules/bare-url": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.2.2.tgz", - "integrity": "sha512-g+ueNGKkrjMazDG3elZO1pNs3HY5+mMmOet1jtKyhOaCnkLzitxf26z7hoAEkDNgdNmnc1KIlt/dw6Po6xZMpA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", "license": "Apache-2.0", "dependencies": { "bare-path": "^3.0.0" @@ -2497,32 +2907,56 @@ "bare-type": "^1.0.6" } }, - "node_modules/bare-wdk-runtime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bare-wdk-runtime/-/bare-wdk-runtime-2.0.0.tgz", - "integrity": "sha512-4rPeYoLJy+VPJxT24yULuNrIwo4Fs5mo7MOVKu82bBez7KjCu8SUj+URPqNoGdymqpEjuEL7YXnXH8SEmAr2Mw==", + "node_modules/bare-v8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bare-v8/-/bare-v8-1.0.1.tgz", + "integrity": "sha512-/cR5ZvFWQRdtTZ4tx0j7TKvTWce8UnnLqm88fwHtJmfM7HODIBVjQGDT7KkDLeD2d/eHP2pzB71Y8/QyiMMKrQ==", + "license": "Apache-2.0" + }, + "node_modules/bare-vm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-vm/-/bare-vm-1.0.0.tgz", + "integrity": "sha512-ideWMfzgoxcyiD4/nM29HZO7Z83W4zY4UMy+uCyJ/BWCRcyD4JVYSxJ8Cz0nYlbJYILhsqL01LqCj4+zMG7OCA==", "license": "Apache-2.0", "dependencies": { - "abort-controller": "^3.0.0", - "bare-assert": "^1.0.2", - "bare-buffer": "^3.2.0", - "bare-crypto": "^1.5.1", - "bare-encoding": "^1.0.0", - "bare-events": "^2.5.4", - "bare-fetch": "^2.3.1", - "bare-fs": "^4.1.6", - "bare-http1": "^4.0.2", + "bare-realm": "^1.0.5" + } + }, + "node_modules/bare-worker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bare-worker/-/bare-worker-4.1.0.tgz", + "integrity": "sha512-Bq+UT/nLhOzouYfkSxvAfj8ovyNpepFP+fN7gbTq7IKL67KnXLRUMm5kNb7x/C/QCgtVMIhmD89LxKrKTgDGZQ==", + "license": "Apache-2.0", + "dependencies": { + "bare-channel": "^5.1.5", + "bare-events": "^2.2.1", + "bare-module": "^6.0.1", + "bare-thread": "^1.1.3" + } + }, + "node_modules/bare-ws": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/bare-ws/-/bare-ws-2.0.4.tgz", + "integrity": "sha512-SQMXzBYna9dRj57Dz1/ag+VWHCRXbfCjMHgyfM2F2lhkVLzMjnVSZP72aVeFWPFqe494Rd70Kzhe2JElGwFlJQ==", + "license": "Apache-2.0", + "dependencies": { + "bare-crypto": "^1.2.0", + "bare-events": "^2.3.1", + "bare-http1": "^4.0.0", "bare-https": "^2.0.0", - "bare-path": "^3.0.0", - "bare-process": "^4.2.1", - "bare-stream": "^2.6.5", - "bare-tcp": "^2.0.5", - "bare-tls": "^2.0.6", - "bare-tty": "^5.0.2", - "bare-url": "^2.1.6", - "bare-utils": "^1.2.1", - "bare-zlib": "^1.3.0", - "event-target-shim": "^5.0.1" + "bare-stream": "^2.1.2" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-url": { + "optional": true + } } }, "node_modules/bare-zlib": { @@ -2535,9 +2969,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.3.tgz", - "integrity": "sha512-mcE+Wr2CAhHNWxXN/DdTI+n4gsPc5QpXpWnyCQWiQYIYZX+ZMJ8juXZgjRa/0/YPJo/NSsgW15/YgmI4nbysYw==", + "version": "2.9.8", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.8.tgz", + "integrity": "sha512-Y1fOuNDowLfgKOypdc9SPABfoWXuZHBOyCS4cD52IeZBhr4Md6CLLs6atcxVrzRmQ06E7hSlm5bHHApPKR/byA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2577,9 +3011,9 @@ } }, "node_modules/browserslist": { - "version": "4.26.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.0.tgz", - "integrity": "sha512-P9go2WrP9FiPwLv3zqRD/Uoxo0RSHjzFCiQz7d4vbmwNqQFo9T9WCeP/Qn5EbcKQY6DBbkxEXNcpJOmncNrb7A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -2597,11 +3031,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.2", - "caniuse-lite": "^1.0.30001741", - "electron-to-chromium": "^1.5.218", - "node-releases": "^2.0.21", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -2638,9 +3072,9 @@ } }, "node_modules/builtins/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -2721,9 +3155,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001741", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz", - "integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==", + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", "dev": true, "funding": [ { @@ -2769,9 +3203,9 @@ } }, "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", "dev": true, "funding": [ { @@ -2785,9 +3219,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.0.tgz", - "integrity": "sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.1.tgz", + "integrity": "sha512-+CmxIZ/L2vNcEfvNtLdU0ZQ6mbq3FZnwAP2PPTiKP+1QOoKwlKlPgb8UKV0Dds7QVaMnHm+FwSft2VB0s/SLjQ==", "dev": true, "license": "MIT" }, @@ -2881,9 +3315,9 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true, "license": "MIT" }, @@ -2907,6 +3341,15 @@ "dev": true, "license": "MIT" }, + "node_modules/compact-encoding": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-2.18.0.tgz", + "integrity": "sha512-goACAOlhMI2xo5jGOMUDfOLnGdRE1jGfyZ+zie8N5114nHrbPIqf6GLUtzbLof6DSyrERlYRm3EcBplte5LcQw==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.3.0" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3028,9 +3471,9 @@ } }, "node_modules/dedent": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", - "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", + "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", "dev": true, "license": "MIT", "peerDependencies": { @@ -3141,9 +3584,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.218", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.218.tgz", - "integrity": "sha512-uwwdN0TUHs8u6iRgN8vKeWZMRll4gBkz+QMqdS7DDe49uiK68/UX92lFb61oiFPrpYZNeZIqa4bA7O6Aiasnzg==", + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", "dev": true, "license": "ISC" }, @@ -3168,9 +3611,9 @@ "license": "MIT" }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3178,9 +3621,9 @@ } }, "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", "dev": true, "license": "MIT", "dependencies": { @@ -3267,27 +3710,27 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", - "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz", + "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", + "es-abstract": "^1.24.1", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", + "es-set-tostringtag": "^2.1.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.6", + "get-intrinsic": "^1.3.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", - "iterator.prototype": "^1.1.4", + "iterator.prototype": "^1.1.5", "safe-array-concat": "^1.1.3" }, "engines": { @@ -3714,9 +4157,9 @@ } }, "node_modules/eslint-plugin-n/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -3948,9 +4391,9 @@ } }, "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -4096,13 +4539,13 @@ "node": ">=0.10.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==", - "license": "MIT", - "engines": { - "node": ">=6" + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" } }, "node_modules/execa": { @@ -4369,6 +4812,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4483,9 +4936,9 @@ } }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -4990,14 +5443,15 @@ } }, "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" }, @@ -5284,9 +5738,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -5853,9 +6307,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -5988,9 +6442,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -6230,9 +6684,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -6337,9 +6791,9 @@ "license": "MIT" }, "node_modules/napi-postinstall": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", - "integrity": "sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "dev": true, "license": "MIT", "bin": { @@ -6367,9 +6821,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", - "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, @@ -6940,7 +7394,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -7048,6 +7501,18 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/require-addon": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.2.0.tgz", + "integrity": "sha512-VNPDZlYgIYQwWp9jMTzljx+k0ZtatKlcvOhktZ/anNPI3dQ9NXk7cq2U4iJ1wd9IrytRnYhyEocFWbkdPb+MYA==", + "license": "Apache-2.0", + "dependencies": { + "bare-addon-resolve": "^1.3.0" + }, + "engines": { + "bare": ">=1.10.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7059,13 +7524,13 @@ } }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -7560,16 +8025,14 @@ } }, "node_modules/streamx": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", - "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", "license": "MIT", "dependencies": { + "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" } }, "node_modules/string-length": { @@ -8155,6 +8618,21 @@ "node": ">=14.17" } }, + "node_modules/udx-native": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.19.2.tgz", + "integrity": "sha512-RNYh+UhfryCsF5hE2ZOuIqcZ+qdipXK3UsarwxWJwsUQZFE3ybwz0mPjwb5ev1PMBcjFahWiepS/q0wwL51c2g==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.5.0", + "bare-events": "^2.2.0", + "require-addon": "^1.1.0", + "streamx": "^2.22.0" + }, + "engines": { + "bare": ">=1.17.4" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -8175,9 +8653,9 @@ } }, "node_modules/undici-types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.11.0.tgz", - "integrity": "sha512-kt1ZriHTi7MU+Z/r9DOdAI3ONdaR3M3csEaRc6ewa4f4dTvX4cQCbJ4NkEn0ohE4hHtq85+PhPSTY+pO/1PwgA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, @@ -8217,9 +8695,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index 8608704..eb07b59 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,11 @@ { - "name": "@wdk/core", - "version": "1.0.0-beta.2", + "name": "@tetherto/wdk", + "version": "1.0.0-beta.5", "description": "A flexible manager that can register and manage multiple wallet instances for different blockchains dynamically.", - "keywords": ["wdk", "core"], + "keywords": [ + "wdk", + "core" + ], "author": "Tether", "license": "Apache-2.0", "repository": { @@ -20,8 +23,8 @@ "test:coverage": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage" }, "dependencies": { - "@wdk/wallet": "https://github.com/davi0kprogramsthings/wdk-wallet#develop", - "bare-wdk-runtime": "2.0.0" + "@tetherto/wdk-wallet": "^1.0.0-beta.6", + "bare-node-runtime": "^1.1.4" }, "devDependencies": { "cross-env": "7.0.3", @@ -39,6 +42,10 @@ "default": "./package.json" } }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, "standard": { "ignore": [ "bare.js", diff --git a/src/errors/PolicyViolationError.js b/src/errors/PolicyViolationError.js new file mode 100644 index 0000000..5a3b004 --- /dev/null +++ b/src/errors/PolicyViolationError.js @@ -0,0 +1,31 @@ +/** @typedef {import('../wdk-manager.js').PolicyTarget} PolicyTarget */ + +/** + * Error thrown when a registered policy rejects an operation. + */ +export class PolicyViolationError extends Error { + /** + * @param {string} policyName + * @param {string} method + * @param {PolicyTarget} target + */ + constructor (policyName, method, target = {}) { + const targetDesc = target.wallet + ? `wallet: ${target.wallet}` + : target.protocol + ? `protocol: ${JSON.stringify(target.protocol)}` + : 'global' + + super( + `Policy "${policyName}" rejected method "${method}" for ${targetDesc}` + ) + + this.name = 'PolicyViolationError' + /** @type {string} */ + this.policy = policyName + /** @type {string} */ + this.method = method + /** @type {Object} */ + this.target = target + } +} diff --git a/src/errors/index.js b/src/errors/index.js new file mode 100644 index 0000000..b6f5df0 --- /dev/null +++ b/src/errors/index.js @@ -0,0 +1 @@ +export { PolicyViolationError } from './PolicyViolationError.js' diff --git a/src/wallet-account-with-protocols.js b/src/wallet-account-with-protocols.js index 0450e0c..245624d 100644 --- a/src/wallet-account-with-protocols.js +++ b/src/wallet-account-with-protocols.js @@ -14,13 +14,15 @@ 'use strict' -import { IWalletAccount, NotImplementedError } from '@wdk/wallet' +import { IWalletAccount, NotImplementedError } from '@tetherto/wdk-wallet' -/** @typedef {import('@wdk/wallet/protocols').ISwapProtocol} ISwapProtocol */ +/** @typedef {import('@tetherto/wdk-wallet/protocols').ISwapProtocol} ISwapProtocol */ -/** @typedef {import('@wdk/wallet/protocols').IBridgeProtocol} IBridgeProtocol */ +/** @typedef {import('@tetherto/wdk-wallet/protocols').IBridgeProtocol} IBridgeProtocol */ -/** @typedef {import('@wdk/wallet/protocols').ILendingProtocol} ILendingProtocol */ +/** @typedef {import('@tetherto/wdk-wallet/protocols').ILendingProtocol} ILendingProtocol */ + +/** @typedef {import('@tetherto/wdk-wallet/protocols').IFiatProtocol} IFiatProtocol */ /** @interface */ export class IWalletAccountWithProtocols extends IWalletAccount { @@ -30,7 +32,7 @@ export class IWalletAccountWithProtocols extends IWalletAccount { * The label must be unique in the scope of the account and the type of protocol (i.e., there can’t be two protocols of the same * type bound to the same account with the same label). * - * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol} P + * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol | typeof FiatProtocol} P * @param {string} label - The label. * @param {P} Protocol - The protocol class. * @param {ConstructorParameters

[1]} config - The protocol configuration. @@ -72,4 +74,15 @@ export class IWalletAccountWithProtocols extends IWalletAccount { getLendingProtocol (label) { throw new NotImplementedError('getLendingProtocol(label)') } + + /** + * Returns the fiat protocol with the given label. + * + * @param {string} label - The label. + * @returns {IFiatProtocol} The fiat protocol. + * @throws {Error} If no fiat protocol has been registered on this account with the given label. + */ + getFiatProtocol (label) { + throw new NotImplementedError('getFiatProtocol(label)') + } } diff --git a/src/wdk-manager.js b/src/wdk-manager.js index 2e64784..9f78ae3 100644 --- a/src/wdk-manager.js +++ b/src/wdk-manager.js @@ -14,27 +14,52 @@ 'use strict' -import WalletManager from '@wdk/wallet' +import WalletManager from '@tetherto/wdk-wallet' -import { SwapProtocol, BridgeProtocol, LendingProtocol } from '@wdk/wallet/protocols' +import { SwapProtocol, BridgeProtocol, LendingProtocol, FiatProtocol } from '@tetherto/wdk-wallet/protocols' -/** @typedef {import('@wdk/wallet').IWalletAccount} IWalletAccount */ +import { PolicyViolationError } from './errors' -/** @typedef {import('@wdk/wallet').FeeRates} FeeRates */ +const INSTANCE_POLICY_SYMBOL = Symbol('wdk_instance_policies') +const INSTANCE_WRAPPED_SYMBOL = Symbol('wdk_instance_wrapped') + +/** @typedef {import('@tetherto/wdk-wallet').IWalletAccount} IWalletAccount */ + +/** @typedef {import('@tetherto/wdk-wallet').FeeRates} FeeRates */ /** @typedef {import('./wallet-account-with-protocols.js').IWalletAccountWithProtocols} IWalletAccountWithProtocols */ /** @typedef {(account: A) => Promise} MiddlewareFunction */ -export default class WdkManager { +/** + * @typedef {Object} PolicyTarget + * @property {string} [blockchain] - The account blockchain identifier this policy applies to. + * @property {Object} [protocol] - The protocol this policy applies to. + * @property {string} [protocol.blockchain] - The blockchain name of the protocol (e.g. "ethereum", "solana"). + * @property {string} [protocol.label] - A protocol label or identifier. + */ + +/** + * @typedef {(method: string, params: any, wallet: any) => boolean|Promise} PolicyEvaluator + */ + +/** + * @typedef {Object} Policy + * @property {string} name - The policy name. + * @property {PolicyTarget} [target] - Scopes the policy to a specific wallet or protocol. + * @property {string|string[]} [method] - The method(s) to gate. If omitted, all methods are gated. + * @property {PolicyEvaluator} evaluate - Evaluates whether the method call is allowed. + */ + +export default class WDK { /** - * Creates a new wallet development kit manager. + * Creates a new wallet development kit instance. * * @param {string | Uint8Array} seed - The wallet's BIP-39 seed phrase. * @throws {Error} If the seed is not valid. */ constructor (seed) { - if (!WdkManager.isValidSeed(seed)) { + if (!WDK.isValidSeed(seed)) { throw new Error('Invalid seed.') } @@ -45,10 +70,16 @@ export default class WdkManager { this._wallets = new Map() /** @private */ - this._protocols = { swap: { }, bridge: { }, lending: { } } + this._protocols = { swap: { }, bridge: { }, lending: { }, fiat: { } } /** @private */ this._middlewares = { } + + /** + * @private + * @type {Array} + */ + this._policies = [] } /** @@ -75,13 +106,143 @@ export default class WdkManager { } /** - * Registers a new wallet to the wdk manager. + * Register one or more wallet policies. + * + * Policies gate all mutating wallet methods. + * + * @param {Array} policies + * @returns {WDK} + */ + registerPolicies (policies = []) { + if (!Array.isArray(policies)) { + throw new TypeError('registerPolicies expects an array') + } + + for (const p of policies) { + if (!p.name || typeof p.evaluate !== 'function') { + throw new TypeError('Invalid policy object') + } + this._policies.push(p) + } + + return this + } + + /** + * Runs policies sequentially. + * + * @param {Array} policies + * @param {string} method + * @param {any} params + * @param {PolicyTarget} target + * @private + */ + async _runPolicies (policies, method, params, target) { + for (const policy of policies) { + const result = await policy.evaluate({ method, params, target }) + + if (!result) { + throw new PolicyViolationError(policy.name, method, target) + } + } + } + + /** + * Applies policies to a specific account or protocol instance. + * Policies are isolated per account. + * + * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol | typeof FiatProtocol | IWalletAccountWithProtocols} P + * @param {P} instance + * @param {PolicyTarget} target + * @returns {P} + * @private + */ + _withPolicyGate (instance, target) { + if (!instance[INSTANCE_POLICY_SYMBOL]) { + Object.defineProperty(instance, INSTANCE_POLICY_SYMBOL, { + value: new Map(), + enumerable: false, + writable: false + }) + } + + if (!instance[INSTANCE_WRAPPED_SYMBOL]) { + Object.defineProperty(instance, INSTANCE_WRAPPED_SYMBOL, { + value: new Set(), + enumerable: false, + writable: false + }) + } + + const methodPolicyMap = instance[INSTANCE_POLICY_SYMBOL] + const wrappedMethods = instance[INSTANCE_WRAPPED_SYMBOL] + + for (const policy of this._policies) { + const policyTarget = policy.target || {} + if (policyTarget.blockchain && policyTarget.blockchain !== target.blockchain) { + continue + } + + if (policyTarget.protocol) { + const policyProtocol = policyTarget.protocol + const targetProto = target.protocol || {} + + if (policyProtocol.blockchain && policyProtocol.blockchain !== targetProto.blockchain) { + continue + } + if (policyProtocol.label && policyProtocol.label !== targetProto.label) continue + } + + let methods = policy.method + if (!methods) { + methods = new Set() + let obj = instance + while (obj && obj !== Object.prototype) { + Object.getOwnPropertyNames(obj) + .filter((prop) => typeof obj[prop] === 'function') + .forEach((prop) => methods.add(prop)) + + obj = Object.getPrototypeOf(obj) + } + } + if (typeof methods === 'string') methods = [methods] + + for (const methodName of methods) { + if (typeof instance[methodName] !== 'function') { + continue + } + + if (!methodPolicyMap.has(methodName)) { + methodPolicyMap.set(methodName, []) + } + + const list = methodPolicyMap.get(methodName) + if (!list.includes(policy)) list.push(policy) + + if (!wrappedMethods.has(methodName)) { + const originalFn = instance[methodName].bind(instance) + instance[methodName] = async (...args) => { + const params = args[0] + const policies = methodPolicyMap.get(methodName) || [] + await this._runPolicies(policies, methodName, params, target) + + return originalFn(...args) + } + + wrappedMethods.add(methodName) + } + } + } + } + + /** + * Registers a new wallet to WDK. * * @template {typeof WalletManager} W * @param {string} blockchain - The name of the blockchain the wallet must be bound to. Can be any string (e.g., "ethereum"). * @param {W} WalletManager - The wallet manager class. * @param {ConstructorParameters[1]} config - The configuration object. - * @returns {WdkManager} The wdk manager. + * @returns {WDK} The wdk instance. */ registerWallet (blockchain, WalletManager, config) { const wallet = new WalletManager(this._seed, config) @@ -92,18 +253,18 @@ export default class WdkManager { } /** - * Registers a new protocol to the wdk manager. + * Registers a new protocol to WDK. * * The label must be unique in the scope of the blockchain and the type of protocol (i.e., there can't be two protocols of the * same type bound to the same blockchain with the same label). * * @see {@link IWalletAccountWithProtocols#registerProtocol} to register protocols only for specific accounts. - * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol} P + * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol | typeof FiatProtocol} P * @param {string} blockchain - The name of the blockchain the protocol must be bound to. Can be any string (e.g., "ethereum"). * @param {string} label - The label. * @param {P} Protocol - The protocol class. * @param {ConstructorParameters

[1]} config - The protocol configuration. - * @returns {WdkManager} The wdk manager. + * @returns {WDK} The wdk instance. */ registerProtocol (blockchain, label, Protocol, config) { if (Protocol.prototype instanceof SwapProtocol) { @@ -118,19 +279,23 @@ export default class WdkManager { this._protocols.lending[blockchain] ??= { } this._protocols.lending[blockchain][label] = { Protocol, config } + } else if (Protocol.prototype instanceof FiatProtocol) { + this._protocols.fiat[blockchain] ??= { } + + this._protocols.fiat[blockchain][label] = { Protocol, config } } return this } /** - * Registers a new middleware to the wdk manager. + * Registers a new middleware to WDK. * * It's possible to register multiple middlewares for the same blockchain, which will be called sequentially. * * @param {string} blockchain - The name of the blockchain the middleware must be bound to. Can be any string (e.g., "ethereum"). * @param {MiddlewareFunction} middleware - A callback function that is called each time the user derives a new account. - * @returns {WdkManager} The wdk manager. + * @returns {WDK} The wdk instance. */ registerMiddleware (blockchain, middleware) { this._middlewares[blockchain] ??= [] @@ -161,6 +326,8 @@ export default class WdkManager { this._registerProtocols(account, { blockchain }) + this._withPolicyGate(account, { blockchain }) + return account } @@ -185,6 +352,8 @@ export default class WdkManager { this._registerProtocols(account, { blockchain }) + this._withPolicyGate(account, { blockchain }) + return account } @@ -229,7 +398,7 @@ export default class WdkManager { /** @private */ _registerProtocols (account, { blockchain }) { - const protocols = { swap: { }, bridge: { }, lending: { } } + const protocols = { swap: { }, bridge: { }, lending: { }, fiat: { } } account.registerProtocol = (label, Protocol, config) => { if (Protocol.prototype instanceof SwapProtocol) { @@ -238,6 +407,8 @@ export default class WdkManager { protocols.bridge[label] = new Protocol(account, config) } else if (Protocol.prototype instanceof LendingProtocol) { protocols.lending[label] = new Protocol(account, config) + } else if (Protocol.prototype instanceof FiatProtocol) { + protocols.fiat[label] = new Protocol(account, config) } return account @@ -248,12 +419,14 @@ export default class WdkManager { const { Protocol, config } = this._protocols.swap[blockchain][label] const protocol = new Protocol(account, config) - + this._withPolicyGate(protocol, { protocol: { blockchain, label } }) return protocol } if (protocols.swap[label]) { - return protocols.swap[label] + const protocol = protocols.swap[label] + this._withPolicyGate(protocol, { protocol: { blockchain, label } }) + return protocol } throw new Error(`No swap protocol registered for label: ${label}.`) @@ -264,12 +437,14 @@ export default class WdkManager { const { Protocol, config } = this._protocols.bridge[blockchain][label] const protocol = new Protocol(account, config) - + this._withPolicyGate(protocol, { protocol: { blockchain, label } }) return protocol } if (protocols.bridge[label]) { - return protocols.bridge[label] + const protocol = protocols.bridge[label] + this._withPolicyGate(protocol, { protocol: { blockchain, label } }) + return protocol } throw new Error(`No bridge protocol registered for label: ${label}.`) @@ -280,15 +455,35 @@ export default class WdkManager { const { Protocol, config } = this._protocols.lending[blockchain][label] const protocol = new Protocol(account, config) - + this._withPolicyGate(protocol, { protocol: { blockchain, label } }) return protocol } if (protocols.lending[label]) { - return protocols.lending[label] + const protocol = protocols.lending[label] + this._withPolicyGate(protocol, { protocol: { blockchain, label } }) + return protocol } throw new Error(`No lending protocol registered for label: ${label}.`) } + + account.getFiatProtocol = (label) => { + if (this._protocols.fiat[blockchain]?.[label]) { + const { Protocol, config } = this._protocols.fiat[blockchain][label] + + const protocol = new Protocol(account, config) + this._withPolicyGate(protocol, { protocol: { blockchain, label } }) + return protocol + } + + if (protocols.fiat[label]) { + const protocol = protocols.fiat[label] + this._withPolicyGate(protocol, { protocol: { blockchain, label } }) + return protocol + } + + throw new Error(`No fiat protocol registered for label: ${label}.`) + } } } diff --git a/tests/wdk-manager.test.js b/tests/wdk-manager.test.js index a93610f..bf3b9ef 100644 --- a/tests/wdk-manager.test.js +++ b/tests/wdk-manager.test.js @@ -1,8 +1,10 @@ -import { beforeEach, describe, expect, jest, test } from '@jest/globals' +'use strict' -import WalletManager from '@wdk/wallet' +import { afterEach, beforeEach, describe, expect, jest, test } from '@jest/globals' -import { BridgeProtocol, LendingProtocol, SwapProtocol } from '@wdk/wallet/protocols' +import WalletManager from '@tetherto/wdk-wallet' + +import { BridgeProtocol, LendingProtocol, SwapProtocol } from '@tetherto/wdk-wallet/protocols' import WdkManager from '../index.js' @@ -433,4 +435,279 @@ describe('WdkManager', () => { expect(disposeMock).toHaveBeenCalled() }) }) + + describe('registerPolicies', () => { + const ETHEREUM_TEST = 'ethereum-test' + const ETHEREUM_LOCAL = 'ethereum-local' + const DUMMY_TX_HASH = '0xdeadbeef1234567890abcdef1234567890abcdef12345678' + const DUMMY_APPROVE_HASH = '0xaaaa1111bbbb2222cccc3333dddd4444eeee5555ffff6666' + const DUMMY_TX_FEE = 21_000_000_000_000n + const DUMMY_BRIDGE_FEE = 5_000_000_000_000n + const DUMMY_SIGNATURE = '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890' + + beforeEach(() => { + getAccountMock.mockReset() + getAccountMock.mockImplementation(() => ({ + getAddress: async () => '0xa460AEbce0d3A4BecAd8ccf9D6D4861296c503Bd', + sendTransaction: jest.fn().mockResolvedValue({ hash: DUMMY_TX_HASH, fee: DUMMY_TX_FEE }), + transfer: jest.fn().mockResolvedValue({ hash: DUMMY_TX_HASH, fee: DUMMY_TX_FEE }), + bridge: jest.fn().mockResolvedValue({ hash: DUMMY_TX_HASH, approveHash: DUMMY_APPROVE_HASH, fee: DUMMY_TX_FEE, bridgeFee: DUMMY_BRIDGE_FEE }), + repay: jest.fn().mockResolvedValue({ hash: DUMMY_TX_HASH, fee: DUMMY_TX_FEE }), + borrow: jest.fn().mockResolvedValue({ hash: DUMMY_TX_HASH, fee: DUMMY_TX_FEE }), + sign: jest.fn().mockResolvedValue(DUMMY_SIGNATURE) + })) + }) + + afterEach(() => { + wdkManager.dispose() + }) + + test('should allow sendTransaction when value is under the global spending limit', async () => { + const MAX_TRANSFER_VALUE = 10n ** 18n + const evaluateMaxTransferPolicy = jest.fn(({ params }) => BigInt(params.value ?? 0n) <= MAX_TRANSFER_VALUE) + const sendParams = { value: 5n * 10n ** 17n } + + wdkManager.registerWallet('ethereum', WalletManagerMock, CONFIG) + wdkManager.registerPolicies([ + { + name: 'max-transfer-1eth', + method: 'sendTransaction', + evaluate: evaluateMaxTransferPolicy + } + ]) + const account = await wdkManager.getAccount('ethereum', 0) + + const result = await account.sendTransaction(sendParams) + + expect(result).toEqual({ hash: DUMMY_TX_HASH, fee: DUMMY_TX_FEE }) + expect(evaluateMaxTransferPolicy).toHaveBeenCalledTimes(1) + expect(evaluateMaxTransferPolicy).toHaveBeenCalledWith({ + method: 'sendTransaction', + params: sendParams, + target: { blockchain: 'ethereum' } + }) + }) + + test('should reject sendTransaction when value is over the global spending limit', async () => { + const MAX_TRANSFER_VALUE = 10n ** 18n + const evaluateMaxTransferPolicy = jest.fn(({ params }) => BigInt(params.value ?? 0n) <= MAX_TRANSFER_VALUE) + const sendParams = { value: 2n * 10n ** 18n } + + wdkManager.registerWallet('ethereum', WalletManagerMock, CONFIG) + wdkManager.registerPolicies([ + { + name: 'max-transfer-1eth', + method: 'sendTransaction', + evaluate: evaluateMaxTransferPolicy + } + ]) + const account = await wdkManager.getAccount('ethereum', 0) + + await expect(account.sendTransaction(sendParams)) + .rejects.toThrow('Policy "max-transfer-1eth" rejected method "sendTransaction" for global') + + expect(evaluateMaxTransferPolicy).toHaveBeenCalledTimes(1) + expect(evaluateMaxTransferPolicy).toHaveBeenCalledWith({ + method: 'sendTransaction', + params: sendParams, + target: { blockchain: 'ethereum' } + }) + }) + + test('should apply a blockchain-targeted policy only to the matching wallet', async () => { + const evaluateEthereumBridgePolicy = jest.fn(() => false) + + wdkManager.registerWallet(ETHEREUM_TEST, WalletManagerMock, CONFIG) + wdkManager.registerWallet('ton', WalletManagerMock, CONFIG) + wdkManager.registerPolicies([ + { + name: 'ethereum-only-bridge', + target: { blockchain: ETHEREUM_TEST }, + method: 'bridge', + evaluate: evaluateEthereumBridgePolicy + } + ]) + const ethereumAccount = await wdkManager.getAccount(ETHEREUM_TEST, 0) + const tonAccount = await wdkManager.getAccount('ton', 0) + + await expect(ethereumAccount.bridge({})) + .rejects.toThrow('Policy "ethereum-only-bridge" rejected method "bridge" for global') + const tonBridgeResult = await tonAccount.bridge({}) + + expect(tonBridgeResult).toEqual({ hash: DUMMY_TX_HASH, approveHash: DUMMY_APPROVE_HASH, fee: DUMMY_TX_FEE, bridgeFee: DUMMY_BRIDGE_FEE }) + expect(evaluateEthereumBridgePolicy).toHaveBeenCalledTimes(1) + expect(evaluateEthereumBridgePolicy).toHaveBeenCalledWith({ + method: 'bridge', + params: {}, + target: { blockchain: ETHEREUM_TEST } + }) + }) + + test('should reject swap when a protocol-targeted policy matches blockchain and label', async () => { + const SwapProtocolMock = jest.fn() + Object.setPrototypeOf(SwapProtocolMock.prototype, SwapProtocol.prototype) + + const evaluateSwapPolicy = jest.fn(() => false) + const swapParams = { tokenIn: 'USDT' } + + wdkManager.registerWallet('ethereum', WalletManagerMock, CONFIG) + wdkManager.registerProtocol('ethereum', 'mainnet', SwapProtocolMock, { swapMaxFee: 100 }) + wdkManager.registerPolicies([ + { + name: 'swap-max-fee', + target: { protocol: { blockchain: 'ethereum', label: 'mainnet' } }, + method: 'swap', + evaluate: evaluateSwapPolicy + } + ]) + const account = await wdkManager.getAccount('ethereum', 0) + const protocol = account.getSwapProtocol('mainnet') + + await expect(protocol.swap(swapParams)) + .rejects.toThrow('Policy "swap-max-fee" rejected method "swap" for protocol: {"blockchain":"ethereum","label":"mainnet"}') + + expect(evaluateSwapPolicy).toHaveBeenCalledTimes(1) + expect(evaluateSwapPolicy).toHaveBeenCalledWith({ + method: 'swap', + params: swapParams, + target: { protocol: { blockchain: 'ethereum', label: 'mainnet' } } + }) + }) + + test('should apply a multi-method policy to each listed account method', async () => { + const evaluateDisableCriticalOpsPolicy = jest.fn(() => false) + const bridgeParams = { route: 'eth-ton' } + const repayParams = { amount: 1n } + const borrowParams = { amount: 2n } + const signParams = { payload: '0xdeadbeef' } + + wdkManager.registerWallet(ETHEREUM_LOCAL, WalletManagerMock, CONFIG) + wdkManager.registerPolicies([ + { + name: 'disable-critical-ops', + target: { blockchain: ETHEREUM_LOCAL }, + method: ['bridge', 'repay', 'borrow'], + evaluate: evaluateDisableCriticalOpsPolicy + } + ]) + const account = await wdkManager.getAccount(ETHEREUM_LOCAL, 0) + + await expect(account.bridge(bridgeParams)) + .rejects.toThrow('Policy "disable-critical-ops" rejected method "bridge" for global') + await expect(account.repay(repayParams)) + .rejects.toThrow('Policy "disable-critical-ops" rejected method "repay" for global') + await expect(account.borrow(borrowParams)) + .rejects.toThrow('Policy "disable-critical-ops" rejected method "borrow" for global') + const signResult = await account.sign(signParams) + + expect(signResult).toBe(DUMMY_SIGNATURE) + expect(evaluateDisableCriticalOpsPolicy).toHaveBeenCalledTimes(3) + expect(evaluateDisableCriticalOpsPolicy).toHaveBeenNthCalledWith(1, { + method: 'bridge', + params: bridgeParams, + target: { blockchain: ETHEREUM_LOCAL } + }) + expect(evaluateDisableCriticalOpsPolicy).toHaveBeenNthCalledWith(2, { + method: 'repay', + params: repayParams, + target: { blockchain: ETHEREUM_LOCAL } + }) + expect(evaluateDisableCriticalOpsPolicy).toHaveBeenNthCalledWith(3, { + method: 'borrow', + params: borrowParams, + target: { blockchain: ETHEREUM_LOCAL } + }) + }) + + test('should await an async policy before allowing a method call', async () => { + const evaluateBusinessHoursPolicy = jest.fn().mockResolvedValue(true) + const signParams = { message: '0xabc' } + + wdkManager.registerWallet('ethereum', WalletManagerMock, CONFIG) + wdkManager.registerPolicies([ + { + name: 'business-hours', + method: 'sign', + evaluate: evaluateBusinessHoursPolicy + } + ]) + const account = await wdkManager.getAccount('ethereum', 0) + + const signResult = await account.sign(signParams) + + expect(signResult).toBe(DUMMY_SIGNATURE) + expect(evaluateBusinessHoursPolicy).toHaveBeenCalledTimes(1) + expect(evaluateBusinessHoursPolicy).toHaveBeenCalledWith({ + method: 'sign', + params: signParams, + target: { blockchain: 'ethereum' } + }) + }) + + test('should stop evaluating policies after the first policy rejects', async () => { + const firstPolicyEvaluator = jest.fn(() => false) + const secondPolicyEvaluator = jest.fn(() => true) + + wdkManager.registerWallet('polygon', WalletManagerMock, CONFIG) + wdkManager.registerPolicies([ + { + name: 'p1', + method: 'sendTransaction', + evaluate: firstPolicyEvaluator + }, + { + name: 'p2', + method: 'sendTransaction', + evaluate: secondPolicyEvaluator + } + ]) + const account = await wdkManager.getAccount('polygon', 0) + + await expect(account.sendTransaction({})) + .rejects.toThrow('Policy "p1" rejected method "sendTransaction" for global') + + expect(firstPolicyEvaluator).toHaveBeenCalledTimes(1) + expect(secondPolicyEvaluator).not.toHaveBeenCalled() + }) + + test('should run a policy without method filter on each called account method', async () => { + const evaluateGlobalPolicy = jest.fn(() => true) + const transferParams = { to: '0xaaa', amount: 11n } + const repayParams = { amount: 22n } + const borrowParams = { amount: 33n } + + wdkManager.registerWallet('ethereum', WalletManagerMock, CONFIG) + wdkManager.registerPolicies([ + { + name: 'global-policy', + evaluate: evaluateGlobalPolicy + } + ]) + const account = await wdkManager.getAccount('ethereum', 0) + + const transferResult = await account.transfer(transferParams) + const repayResult = await account.repay(repayParams) + const borrowResult = await account.borrow(borrowParams) + + expect(transferResult).toEqual({ hash: DUMMY_TX_HASH, fee: DUMMY_TX_FEE }) + expect(repayResult).toEqual({ hash: DUMMY_TX_HASH, fee: DUMMY_TX_FEE }) + expect(borrowResult).toEqual({ hash: DUMMY_TX_HASH, fee: DUMMY_TX_FEE }) + expect(evaluateGlobalPolicy).toHaveBeenCalledTimes(3) + expect(evaluateGlobalPolicy).toHaveBeenNthCalledWith(1, { + method: 'transfer', + params: transferParams, + target: { blockchain: 'ethereum' } + }) + expect(evaluateGlobalPolicy).toHaveBeenNthCalledWith(2, { + method: 'repay', + params: repayParams, + target: { blockchain: 'ethereum' } + }) + expect(evaluateGlobalPolicy).toHaveBeenNthCalledWith(3, { + method: 'borrow', + params: borrowParams, + target: { blockchain: 'ethereum' } + }) + }) + }) }) diff --git a/types/src/errors/PolicyViolationError.d.ts b/types/src/errors/PolicyViolationError.d.ts new file mode 100644 index 0000000..8dc24ca --- /dev/null +++ b/types/src/errors/PolicyViolationError.d.ts @@ -0,0 +1,19 @@ +/** @typedef {import('../wdk-manager.js').PolicyTarget} PolicyTarget */ +/** + * Error thrown when a registered policy rejects an operation. + */ +export class PolicyViolationError extends Error { + /** + * @param {string} policyName + * @param {string} method + * @param {PolicyTarget} target + */ + constructor(policyName: string, method: string, target?: PolicyTarget); + /** @type {string} */ + policy: string; + /** @type {string} */ + method: string; + /** @type {Object} */ + target: any; +} +export type PolicyTarget = import("../wdk-manager.js").PolicyTarget; diff --git a/types/src/errors/index.d.ts b/types/src/errors/index.d.ts new file mode 100644 index 0000000..ced3fcf --- /dev/null +++ b/types/src/errors/index.d.ts @@ -0,0 +1 @@ +export { PolicyViolationError } from "./PolicyViolationError.js"; diff --git a/types/src/wallet-account-with-protocols.d.ts b/types/src/wallet-account-with-protocols.d.ts index b99b7cc..1934786 100644 --- a/types/src/wallet-account-with-protocols.d.ts +++ b/types/src/wallet-account-with-protocols.d.ts @@ -6,13 +6,13 @@ export interface IWalletAccountWithProtocols extends IWalletAccount { * The label must be unique in the scope of the account and the type of protocol (i.e., there can’t be two protocols of the same * type bound to the same account with the same label). * - * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol} P + * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol | typeof FiatProtocol} P * @param {string} label - The label. * @param {P} Protocol - The protocol class. * @param {ConstructorParameters

[1]} config - The protocol configuration. * @returns {IWalletAccountWithProtocols} The account. */ - registerProtocol

(label: string, Protocol: P, config: ConstructorParameters

[1]): IWalletAccountWithProtocols; + registerProtocol

(label: string, Protocol: P, config: ConstructorParameters

[1]): IWalletAccountWithProtocols; /** * Returns the swap protocol with the given label. * @@ -37,9 +37,18 @@ export interface IWalletAccountWithProtocols extends IWalletAccount { * @throws {Error} If no lending protocol has been registered on this account with the given label. */ getLendingProtocol(label: string): ILendingProtocol; + /** + * Returns the fiat protocol with the given label. + * + * @param {string} label - The label. + * @returns {IFiatProtocol} The fiat protocol. + * @throws {Error} If no fiat protocol has been registered on this account with the given label. + */ + getFiatProtocol(label: string): IFiatProtocol; } -export type ISwapProtocol = import("@wdk/wallet/protocols").ISwapProtocol; -export type IBridgeProtocol = import("@wdk/wallet/protocols").IBridgeProtocol; -export type ILendingProtocol = import("@wdk/wallet/protocols").ILendingProtocol; -import { IWalletAccount } from "@wdk/wallet"; -import { SwapProtocol, BridgeProtocol, LendingProtocol } from "@wdk/wallet/protocols"; +export type ISwapProtocol = import("@tetherto/wdk-wallet/protocols").ISwapProtocol; +export type IBridgeProtocol = import("@tetherto/wdk-wallet/protocols").IBridgeProtocol; +export type ILendingProtocol = import("@tetherto/wdk-wallet/protocols").ILendingProtocol; +export type IFiatProtocol = import("@tetherto/wdk-wallet/protocols").IFiatProtocol; +import { IWalletAccount } from "@tetherto/wdk-wallet"; +import { SwapProtocol, BridgeProtocol, LendingProtocol, FiatProtocol } from "@tetherto/wdk-wallet/protocols"; \ No newline at end of file diff --git a/types/src/wdk-manager.d.ts b/types/src/wdk-manager.d.ts index d3caf3c..cf4f648 100644 --- a/types/src/wdk-manager.d.ts +++ b/types/src/wdk-manager.d.ts @@ -27,6 +27,41 @@ export default class WdkManager { private _protocols; /** @private */ private _middlewares; + /** + * @private + * @type {Array} + */ + private _policies; + /** + * Register one or more wallet policies. + * + * Policies gate all mutating wallet methods. + * + * @param {Array} policies + * @returns {WdkManager} + */ + registerPolicies(policies?: Array): WdkManager; + /** + * Runs policies sequentially. + * + * @param {Array} policies + * @param {string} method + * @param {any} params + * @param {PolicyTarget} target + * @private + */ + private _runPolicies; + /** + * Applies policies to a specific account or protocol instance. + * Policies are isolated per account. + * + * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol | typeof FiatProtocol | IWalletAccountWithProtocols} P + * @param {P} instance + * @param {PolicyTarget} target + * @returns {P} + * @private + */ + private _withPolicyGate; /** * Registers a new wallet to the wdk manager. * @@ -44,14 +79,14 @@ export default class WdkManager { * same type bound to the same blockchain with the same label). * * @see {@link IWalletAccountWithProtocols#registerProtocol} to register protocols only for specific accounts. - * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol} P + * @template {typeof SwapProtocol | typeof BridgeProtocol | typeof LendingProtocol | typeof FiatProtocol} P * @param {string} blockchain - The name of the blockchain the protocol must be bound to. Can be any string (e.g., "ethereum"). * @param {string} label - The label. * @param {P} Protocol - The protocol class. * @param {ConstructorParameters

[1]} config - The protocol configuration. * @returns {WdkManager} The wdk manager. */ - registerProtocol

(blockchain: string, label: string, Protocol: P, config: ConstructorParameters

[1]): WdkManager; + registerProtocol

(blockchain: string, label: string, Protocol: P, config: ConstructorParameters

[1]): WDK; /** * Registers a new middleware to the wdk manager. * @@ -97,11 +132,44 @@ export default class WdkManager { /** @private */ private _registerProtocols; } -export type IWalletAccount = import("@wdk/wallet").IWalletAccount; -export type FeeRates = import("@wdk/wallet").FeeRates; +export type IWalletAccount = import("@tetherto/wdk-wallet").IWalletAccount; +export type FeeRates = import("@tetherto/wdk-wallet").FeeRates; export type IWalletAccountWithProtocols = import("./wallet-account-with-protocols.js").IWalletAccountWithProtocols; export type MiddlewareFunction = (account: A) => Promise; -import WalletManager from "@wdk/wallet"; -import { SwapProtocol } from "@wdk/wallet/protocols"; -import { BridgeProtocol } from "@wdk/wallet/protocols"; -import { LendingProtocol } from "@wdk/wallet/protocols"; +export type PolicyTarget = { + /** + * - The account blockchain identifier this policy applies to. + */ + blockchain?: string; + /** + * - The protocol this policy applies to. + */ + protocol?: { + blockchain?: string; + label?: string; + }; +}; +export type PolicyEvaluator = (method: string, params: any, wallet: any) => boolean | Promise; +export type Policy = { + /** + * - The policy name. + */ + name: string; + /** + * - Scopes the policy to a specific wallet or protocol. + */ + target?: PolicyTarget; + /** + * - The method(s) to gate. If omitted, all methods are gated. + */ + method?: string | string[]; + /** + * - Evaluates whether the method call is allowed. + */ + evaluate: PolicyEvaluator; +}; +import WalletManager from "@tetherto/wdk-wallet"; +import { SwapProtocol } from "@tetherto/wdk-wallet/protocols"; +import { BridgeProtocol } from "@tetherto/wdk-wallet/protocols"; +import { LendingProtocol } from "@tetherto/wdk-wallet/protocols"; +import { FiatProtocol } from "@tetherto/wdk-wallet/protocols"; \ No newline at end of file